single page applications on javascript and asp.net mvc4

30
SINGLE PAGE APPLICATIONS WITH JAVASCRIPT AND ASP.NET MVC4 Author: Yurii Shapovalov [email protected]

Upload: yuriy-shapovalov

Post on 17-May-2015

7.371 views

Category:

Technology


7 download

DESCRIPTION

Single page applications on JavaScript and asp.net mvc4 from Minsk SEC 2013 conference (Jan 2013)

TRANSCRIPT

Page 1: Single Page Applications on JavaScript and ASP.NET MVC4

SINGLE PAGE APPLICATIONS WITH JAVASCRIPT AND ASP.NET MVC4

Author: Yurii [email protected]

Page 2: Single Page Applications on JavaScript and ASP.NET MVC4

TOPICS

Definition

SPA Architecture

Server Stack

Client Stack

JavaScript Patterns

Web Optimization

Examples of components

Page 3: Single Page Applications on JavaScript and ASP.NET MVC4

WHAT’S A SPA?

• is a web application that fits on a single web page, providing a fluid UX akin to a desktop application.

• Maintain navigation, history, page linking.

• Whole applications fits on a single web page.

• Persisting important state on the client

• Fully (or mostly) loaded in the initial page load

• Progressively downloads data as required

Page 4: Single Page Applications on JavaScript and ASP.NET MVC4

SPA HIGH LEVEL ARCHITECTURE

Server Client

Database

Data Services

ASP.NET + (JavaScript /

HTML / CSS)

Application(JavaScript)

Views (HTML / CSS)

Data Access(JavaScript)

Navigation

Page 5: Single Page Applications on JavaScript and ASP.NET MVC4

SERVER SIDE DESIGN

Database

Repository Pattern

Unit of Work Pattern

Entity Framework

Web API JSON

EF Code First

ASP.NET Web API

Page 6: Single Page Applications on JavaScript and ASP.NET MVC4

ASP.NET WEB API

• Simplifies web services

•Good for serving JSON

SQL Server Data LayerASP.NET Web

API

Models

JSON

Page 7: Single Page Applications on JavaScript and ASP.NET MVC4

CONTROLLERSpublic IEnumerable<Activity> GetAll() { return Uow.Activities.GetAll().OrderBy(p => p.Name);}

public Activity Get(int id) { var activity = Uow.Activities.GetById(id); if(activity != null) return activity;}

public HttpResponseMessage Put(Activity activity) { Uow.Activities.Update(activity); Uow.Commit(); return new HttpResponseMessage(HttpStatusCode.NoContent);}}

Page 8: Single Page Applications on JavaScript and ASP.NET MVC4

INDEX.HTML

•Using HTML5 Boilerplate• (http://html5boilerplate.com/)• Modernizr.js – checks supported features in client browser.

•@using System.Web.Optimization

• Configuring App_Start• BundleConfig

Page 9: Single Page Applications on JavaScript and ASP.NET MVC4

BUNDLING AND MINIFICATION

• To reduce size of resources which we transfer to client in initial page load, we are using bundling and minification.

• Bundling reduce server calls for resources.

• Minification reduce the size of file.

Page 10: Single Page Applications on JavaScript and ASP.NET MVC4

BUNDLING

• Instead of this:

<script type="text/javascript" src="jquery.easing.js"></script>

<script type="text/javascript" src="jquery-ui.js"></script>

<script type="text/javascript" src="inputlabel.js"></script>

<script type="text/javascript" src="jquery.treeview.js"></script>

<script type="text/javascript “src="quickpager.jquery.js"></script>

<script type="text/javascript" src="jquery.modalboxmin.js"></script>

<script type="text/javascript" src="jquery.activity-indi.js"></script>

<script type="text/javascript" src="/lib/js/tabs.js"></script>

<script type="text/javascript" src="/lib/js/socializ.js"></script>

<script type="text/javascript" src="/lib/js/muScript.js"></script>

<!-- ... -->

Page 11: Single Page Applications on JavaScript and ASP.NET MVC4

BUNDLING

… doing this for scripts:

public static void RegisterBundles(BundleCollection bundles)

{

bundles.Add(new ScriptBundle("~/bundles/jsextlibs").Include(

"~/Scripts/lib/jquery.activity-indicator-{version}.js",

"~/Scripts/lib/knockout-{version}.js",

"~/Scripts/lib/underscore.js",

"~/Scripts/lib/moment.js",

"~/Scripts/lib/sammy.js",

"~/Scripts/lib/amplify.js"

// ...

));

Page 12: Single Page Applications on JavaScript and ASP.NET MVC4

BUNDLING

… and for other resources:bundles.Add(new ScriptBundle("~/bundles/jsapplibs").

IncludeDirectory("~/Scripts/app/", "*.js",

searchSubdirectories: false));

bundles.Add(new StyleBundle("~/Content/css").

Include(

"~/Content/normalize.css",

"~/Content/main.css", ));

bundles.Add(new Bundle("~/Content/Less",

new LessTransform(), new CssMinify())

.Include("~/Content/styles.less"));

Page 13: Single Page Applications on JavaScript and ASP.NET MVC4

BUNDLING

Add bundles on [email protected]("~/Content/css", "~/Content/less")

@Scripts.Render("~/bundles/modernizr")

@Scripts.Render(

"~/bundles/jquery",

"~/bundles/jsextlibs",

"~/Scripts/lib/require.js",

"~/bundles/jsapplibs",

"~/bundles/jsmocks",

"~/Scripts/main.js"

)

Page 14: Single Page Applications on JavaScript and ASP.NET MVC4

BUNDLING AND MINIFICATION

  Using B/M Without B/MChange

File Requests

9 34 256%

KB Sent 3.26 11.92 266%

KB Received

388.51 530 36%

Load Time

510 MS 780 MS 53%

Page 15: Single Page Applications on JavaScript and ASP.NET MVC4

CSS AND LESS

Less – Dynamic Stylesheet language

.accent-top (@sizeMultiplier: 1, @lineHeightMultiplier: 1) {

.accent;

width: @base-accent-top-width * @sizeMultiplier;

height: @base-accent-top-height * @sizeMultiplier;

div {

text-transform: uppercase;

}}

Page 16: Single Page Applications on JavaScript and ASP.NET MVC4

LESS TO CSS

Creating custom BundleTransform using library dotLett.

public class LessTransform : IBundleTransform

{

public void Process(BundleContext c, BundleResponse resp)

{

resp.Content = dotless.Core.Less.Parse(resp.Content);

response.ContentType = "text/css";

}}

Page 17: Single Page Applications on JavaScript and ASP.NET MVC4

RENDER VIEWS

• Render all pages in main section.• All pages are stored in Views folder• General components like header, navigation and footer we are defining above or below of main section.

<section class="main">

@RenderPage("Views/workspace.cshtml")

@RenderPage("Views/statistics.cshtml")

@RenderPage("Views/settings.cshtml")

@* ... *@

</section>

Page 18: Single Page Applications on JavaScript and ASP.NET MVC4

VIEWS

• View is a simple html with data-bind.• Views might contain Knockout templates

<section id="workspace-view" class="view">

<h2 data-bind="text: context.date"></h2>

<ul data-bind="template: { name: 'activity-template',

foreach: activities }" class="activity"></ul>

<button data-bind="click: addActivity" class="add- activity">+</button>

<table data-bind="template: { name: timelogTemplate }">

</table>

</section>

Page 19: Single Page Applications on JavaScript and ASP.NET MVC4

CLIENT SIDE DESIGN

BootstrapperHTML ViewsHTML ViewsHTML Views

HTML / ViewsMVVM Binder Data Primer

Data Context

Data Services

Model MappersModel MappersModel MappersModel Mappers

SortingHTML / ViewsHTML / ViewsHTML / Views

ViewModels

HTML / ViewsHTML / ViewsHTML / ViewsModelsFiltering

Page 20: Single Page Applications on JavaScript and ASP.NET MVC4

JAVASCRIPT LIBRARIES

jQuery Working with DOM,

Knockout.js Data Binding and MVVM

Amplify.js Data Push/Pull, Caching, Client Storage

Breeze.js Querying with filters, ordering and paging

Sammy.js Navigation and History

require.js Dependency Resolution

underscore.js JavaScript helper

toastr.js UI Alerts

qunit Unit Testing

Page 21: Single Page Applications on JavaScript and ASP.NET MVC4

JAVASCRIPT PATTERNS

• AMD (Asynchronous Module Definition)• is a JavaScript API for defining modules and their dependencies in such a way that modules may be asynchronously loaded

• Revealing Module Pattern• we define all of our functions and variables in the private scope and return an anonymous object with pointers to the private functionality we wished to reveal as public.

• MVVM

Page 22: Single Page Applications on JavaScript and ASP.NET MVC4

AMD PATTERN

Application

Data Context

Controller

Data Services Model

Navigation

• Sequence of loading component might cause an issue.

Page 23: Single Page Applications on JavaScript and ASP.NET MVC4

DEFINING A MODULE IN REQUIRE.JS

define('model',

[‘settings', 'model.workspace'],

function (settings, workspace) {

var

model = {

Workspace: workspace

}; // ...

return model;

});

Module ID

Dependencies

Module Factory

Page 24: Single Page Applications on JavaScript and ASP.NET MVC4

STARTING THE SPA

Prime the Data

Models

Data Services

Data Context

Setup the presentation

Navigation Router

HTML Views

View Models

Bootstrapper

Page 25: Single Page Applications on JavaScript and ASP.NET MVC4

BOOTSTRAPPER

Bootstrapper responsible for initial application run.define('bootstrapper',['jquery', 'route-config', 'presenter', 'dataprimer', 'binder'], function ($, routeConfig, presenter, dataprimer, binder) { var run = function () { presenter.toggleActivity(true); $.when(dataprimer.fetch()) .done(binder.bind) .done(routeConfig.register) .always(function () { presenter.toggleActivity(false); }); } return { run : run }});

var run = function () {

presenter.toggleActivity(true);

$.when(dataprimer.fetch())

.done(binder.bind)

.done(routeConfig.register)

.always(function () {

presenter.toggleActivity(false);

}}

Page 26: Single Page Applications on JavaScript and ASP.NET MVC4

DATASERVICE var init = function () { amplify.request.define('activities', 'ajax', { url: '/api/activities', dataType: 'json', type: 'GET' }); },

getActivities = function (callbacks) { return amplify.request({ resourceId: 'activities', data: '', success: callbacks.success, error: callbacks.error });}; init();

return { getActivities: getActivities };

Page 27: Single Page Applications on JavaScript and ASP.NET MVC4

VIEWMODEL activityItemTemplate = 'common.activityitem', timelogTemplate = 'common.timelogtable'; activities = ko.observableArray();

activate = function (routerData, callback) { refresh(callback); } getWorkspace = function (callback) { datacontext.activities.getActivities(id); } return {

activate: activate activityItemTemplate: activityItemTemplate, timelogTemplate: timelogTemplate }});

Page 28: Single Page Applications on JavaScript and ASP.NET MVC4

AS RESULT WE HAVE

• Async services• Client side application & business logic• Long-lived client-side state• 2 way data binding• Tombstoning / dropped connection

Page 29: Single Page Applications on JavaScript and ASP.NET MVC4

PROS AND CONS

• Faster UI• More Interactive• Can work offline• UI is just another

Client• UI can have BI• Perfect for

HTML5 and Mobile apps

• Bad for SEO

• More complex to build

• Need to expose application logic to client

• Require strong JavaScript skills

Page 30: Single Page Applications on JavaScript and ASP.NET MVC4

QUESTIONS?

Yurii Shapovalov

Email: [email protected]

Skype: Shapovalov.Yuriy