Diese Präsentation wurde erfolgreich gemeldet.
Wir verwenden Ihre LinkedIn Profilangaben und Informationen zu Ihren Aktivitäten, um Anzeigen zu personalisieren und Ihnen relevantere Inhalte anzuzeigen. Sie können Ihre Anzeigeneinstellungen jederzeit ändern.
SINGLE PAGE
APPLICATIONS WITH
JAVASCRIPT AND ASP.NET
MVC4

Author: Yurii Shapovalov
Yurii_Shapovalov@epam.com
TOPICS
 Definition
 SPA Architecture
 Server Stack
 Client Stack
 JavaScript Patterns
 Web Optimization
 Examples o...
WHAT’S A SPA?
• is a web application that fits on a single web page, providing a fluid

UX akin to a desktop application.
...
SPA HIGH LEVEL
ARCHITECTURE
Server

Client

ASP.NET
+ (JavaScript /
HTML / CSS)

Views
(HTML / CSS)

Data Services

Applic...
SERVER SIDE DESIGN
Web API

ASP.NET Web API

Unit of Work Pattern

Repository Pattern

Entity Framework

EF Code First

Da...
ASP.NET WEB API
• Simplifies web services

• Good for serving JSON
JSON
Models

SQL Server

Data Layer

ASP.NET Web
API
CONTROLLERS
public IEnumerable<Activity> GetAll()
{
return Uow.Activities.GetAll().OrderBy(p => p.Name);
}
public Activity...
INDEX.HTML
• Using HTML5 Boilerplate
• (http://html5boilerplate.com/)
• Modernizr.js – checks supported features in client...
BUNDLING AND MINIFICATION
• To reduce size of resources which we transfer to

client in initial page load, we are using bu...
BUNDLING
• Instead of this:
<script type="text/javascript" src="jquery.easing.js"></script>
<script type="text/javascript"...
BUNDLING
… doing this for scripts:
public static void RegisterBundles(BundleCollection bundles)
{
bundles.Add(new ScriptBu...
BUNDLING
… and for other resources:
bundles.Add(new ScriptBundle("~/bundles/jsapplibs").
IncludeDirectory("~/Scripts/app/"...
BUNDLING
Add bundles on index.html
@Styles.Render("~/Content/css", "~/Content/less")
@Scripts.Render("~/bundles/modernizr"...
BUNDLING AND MINIFICATION
Using B/M

Without B/M

Chang
e

File
Requests

9

34

256%

KB Sent

3.26

11.92

266%

KB
Rece...
CSS AND LESS
Less – Dynamic Stylesheet language
.accent-top (@sizeMultiplier: 1, @lineHeightMultiplier: 1)
{
.accent;
widt...
LESS TO CSS
 Creating custom BundleTransform using library dotLett.

public class LessTransform : IBundleTransform
{
publ...
RENDER VIEWS
• Render all pages in main section.
• All pages are stored in Views folder
• General components like header, ...
VIEWS
• View is a simple html with data-bind.
• Views might contain Knockout templates
<section id="workspace-view" class=...
CLIENT SIDE DESIGN
HTML Views
HTML Views
HTML Views
HTML / Views

Bootstrapper
MVVM Binder

HTML / Views
HTML / Views
HTML...
JAVASCRIPT LIBRARIES
jQuery

Working with DOM,

Knockout.js

Data Binding and MVVM

Amplify.js

Data Push/Pull, Caching, C...
JAVASCRIPT PATTERNS
• AMD (Asynchronous Module Definition)
• is a JavaScript API for defining modules and their
dependenci...
AMD PATTERN
Application

Controller

Navigation

Data Services

Data Context

Model

• Sequence of loading component might...
DEFINING A MODULE IN
REQUIRE.JS
Module ID
define('model',

Dependencies

[‘settings', 'model.workspace'],
function (settin...
STARTING THE SPA
Bootstrapper

Prime the Data

Setup the presentation

Data Services

HTML Views

Data Context

View Model...
BOOTSTRAPPER
Bootstrapper responsible for initial application run.
define('bootstrapper',
var run = function () {

['jquer...
DATASERVICE
var init = function () {
amplify.request.define('activities', 'ajax', {
url: '/api/activities',
dataType: 'jso...
VIEWMODEL
activityItemTemplate = 'common.activityitem',
timelogTemplate = 'common.timelogtable';
activities = ko.observabl...
AS RESULT WE HAVE
• Async services
• Client side application & business logic

• Long-lived client-side state
• 2 way data...
PROS AND CONS
• Faster UI

• Bad for SEO

• More Interactive

• More complex to build

• Can work offline

• Need to expos...
QUESTIONS?
Yurii Shapovalov
Email: Yurii_Shapovalov@epam.com
Skype: Shapovalov.Yuriy
Nächste SlideShare
Wird geladen in …5
×

Single Page Applications on JavaScript and ASP.NET MVC4

8.856 Aufrufe

Veröffentlicht am

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

Veröffentlicht in: Technologie
  • ➤➤ How Long Does She Want You to Last? Here's the link to the FREE report ★★★ https://tinyurl.com/rockhardxx
       Antworten 
    Sind Sie sicher, dass Sie …  Ja  Nein
    Ihre Nachricht erscheint hier

Single Page Applications on JavaScript and ASP.NET MVC4

  1. 1. SINGLE PAGE APPLICATIONS WITH JAVASCRIPT AND ASP.NET MVC4 Author: Yurii Shapovalov Yurii_Shapovalov@epam.com
  2. 2. TOPICS  Definition  SPA Architecture  Server Stack  Client Stack  JavaScript Patterns  Web Optimization  Examples of components
  3. 3. 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
  4. 4. SPA HIGH LEVEL ARCHITECTURE Server Client ASP.NET + (JavaScript / HTML / CSS) Views (HTML / CSS) Data Services Application (JavaScript) Database Data Access (JavaScript) Navigation
  5. 5. SERVER SIDE DESIGN Web API ASP.NET Web API Unit of Work Pattern Repository Pattern Entity Framework EF Code First Database JSON
  6. 6. ASP.NET WEB API • Simplifies web services • Good for serving JSON JSON Models SQL Server Data Layer ASP.NET Web API
  7. 7. CONTROLLERS public 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); }}
  8. 8. INDEX.HTML • Using HTML5 Boilerplate • (http://html5boilerplate.com/) • Modernizr.js – checks supported features in client browser. • @using System.Web.Optimization • Configuring App_Start • BundleConfig
  9. 9. 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.
  10. 10. 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> <!-- ... -->
  11. 11. 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" // ... ));
  12. 12. 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"));
  13. 13. BUNDLING Add bundles on index.html @Styles.Render("~/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" )
  14. 14. BUNDLING AND MINIFICATION Using B/M Without B/M Chang e File Requests 9 34 256% KB Sent 3.26 11.92 266% KB Received 388.51 530 36% 780 MS 53% Load Time 510 MS
  15. 15. 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; }}
  16. 16. 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"; }}
  17. 17. 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>
  18. 18. 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="addactivity">+</button> <table data-bind="template: { name: timelogTemplate }"> </table> </section>
  19. 19. CLIENT SIDE DESIGN HTML Views HTML Views HTML Views HTML / Views Bootstrapper MVVM Binder HTML / Views HTML / Views HTML / Views ViewModels Sorting Filtering Data Primer HTML / Views HTML / Views HTML / Views Models Data Context Data Services Model Mappers Model Mappers Model Mappers Model Mappers
  20. 20. 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
  21. 21. 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
  22. 22. AMD PATTERN Application Controller Navigation Data Services Data Context Model • Sequence of loading component might cause an issue.
  23. 23. DEFINING A MODULE IN REQUIRE.JS Module ID define('model', Dependencies [‘settings', 'model.workspace'], function (settings, workspace) { var model = { Workspace: workspace }; // ... return model; }); Module Factory
  24. 24. STARTING THE SPA Bootstrapper Prime the Data Setup the presentation Data Services HTML Views Data Context View Models Models Navigation Router
  25. 25. BOOTSTRAPPER Bootstrapper responsible for initial application run. define('bootstrapper', var run = function () { ['jquery', 'route-config', 'presenter', 'dataprimer', 'binder'], function ($, routeConfig, presenter, dataprimer, binder) { presenter.toggleActivity(true); var run = function () { $.when(dataprimer.fetch()) presenter.toggleActivity(true); $.when(dataprimer.fetch()) .done(binder.bind) .done(binder.bind) .done(routeConfig.register) .done(routeConfig.register) .always(function () { presenter.toggleActivity(false); .always(function () { }); } presenter.toggleActivity(false); return { run : run }} }});
  26. 26. 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 };
  27. 27. 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 }});
  28. 28. AS RESULT WE HAVE • Async services • Client side application & business logic • Long-lived client-side state • 2 way data binding • Tombstoning / dropped connection
  29. 29. PROS AND CONS • Faster UI • Bad for SEO • More Interactive • More complex to build • Can work offline • Need to expose application logic to client • UI is just another Client • UI can have BI • Perfect for HTML5 and Mobile apps • Require strong JavaScript skills
  30. 30. QUESTIONS? Yurii Shapovalov Email: Yurii_Shapovalov@epam.com Skype: Shapovalov.Yuriy

×