Single Page Applications on JavaScript and ASP.NET MVC4

8,611 views

Published on

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

Published in: Technology
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
8,611
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
48
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide
  • Today we are going to talk about how to build Single Page Application using ASP.NET MVC4 and JavaScript with bunch of libraries.So, let’s start.
  • Here is briefly a topics to discuss today. I will focus mostly on client side, because it’s usually much more complex than server side for Single Page Applications.
  • What is a SPA, (definition from Wikipedia)Sounds like a simple concept, right?What else specific options we can define, which relates to SPA?Application maintain navigation, history of transitions. And application!, but not browser responsible for linking of all pages (or views in terms of SPA).Whole application fits on a single web page. So we don’t need to refresh the page when user click to some internal link.Persisting important state on the client. Server might know nothing what view are opened on clients side, all such information are stored on client.Fully loaded on the initial page load, and progressively downloads data as required.
  • Typical high level architecture consists of client and server side.On server side we have database, ASP.NET services, which transfer to client all required resources, HTML, CSS, JavaScript)And Data Services which responsible for data access, and asynchronous communication with application.Client side has initialialized HTML page (only one html page per application), CSS files.And JavaScript which might be splitted to several components: Application (component contain business logic)Navigation (maintain transition between views)And Data Access layer which support communication between services, and asynchronous data loading.When client call our application, server returns all required stuff, and call initialization procedure when everything is downloaded.Initialization procedure prepare all components, apply settings. As result, we have complete web application on clientApplication communicate services through Data Access component, and retrieve data on demand.
  • Server side store the data, so, database on server side is a key component. ORM like EntityFramework will help to access data in DB. Data layer consists of several patterns which provide data in consistent way, and decouple operations and data.Repository pattern which isolate objects from code for accessing them.Unit of work – maintain set of repositories, and manage commit operations, also handles concurrency issues.And our services are exposed in Web API, which is implemented with ASP.NET Web API and using JSON format for transferring data to the client.
  • ASP.NET providing asynchronous services to client, it works with data layer, receive required entities or collections of entities, and transfer them to client in JSON format.
  • Typical controller looks like this.Operations call UnitOfWork and define which repository need to use. Call the operation in this repository, and apply some filter or ordering for received data.Than transfer it to client.(I have reduce size of methods, remove exception handling, input values validation, and business logic, just to simplify example, but it’s not ready to production code.)
  • I’m sure most of you have seen such html code. It usually stands in head files, or at the end of the body.Let me ask you a question, what will do browser? …Yes, it will send to server bunch or requests for each file.And server of course return these files, usually with tabs, spaces, some developers comments.So, you probably get my point, we need to minify these files, and transfer them to client in one response.
  • What is a SPA, (definition from Wikipedia)Sounds like a simple concept, right?What else specific options we can define, which relates to SPA?Application maintain navigation, history of transitions. And application!, but not browser responsible for linking of all pages (or views in terms of SPA).Whole application fits on a single web page. So we don’t need to refresh the page when user click to some internal link.Persisting important state on the client. Server might know nothing what view are opened on clients side, all such information are stored on client.Fully loaded on the initial page load, and progressively downloads data as required.
  • What is a SPA, (definition from Wikipedia)Sounds like a simple concept, right?What else specific options we can define, which relates to SPA?Application maintain navigation, history of transitions. And application!, but not browser responsible for linking of all pages (or views in terms of SPA).Whole application fits on a single web page. So we don’t need to refresh the page when user click to some internal link.Persisting important state on the client. Server might know nothing what view are opened on clients side, all such information are stored on client.Fully loaded on the initial page load, and progressively downloads data as required.
  • What is a SPA, (definition from Wikipedia)Sounds like a simple concept, right?What else specific options we can define, which relates to SPA?Application maintain navigation, history of transitions. And application!, but not browser responsible for linking of all pages (or views in terms of SPA).Whole application fits on a single web page. So we don’t need to refresh the page when user click to some internal link.Persisting important state on the client. Server might know nothing what view are opened on clients side, all such information are stored on client.Fully loaded on the initial page load, and progressively downloads data as required.
  • What is a SPA, (definition from Wikipedia)Sounds like a simple concept, right?What else specific options we can define, which relates to SPA?Application maintain navigation, history of transitions. And application!, but not browser responsible for linking of all pages (or views in terms of SPA).Whole application fits on a single web page. So we don’t need to refresh the page when user click to some internal link.Persisting important state on the client. Server might know nothing what view are opened on clients side, all such information are stored on client.Fully loaded on the initial page load, and progressively downloads data as required.
  • What is a SPA, (definition from Wikipedia)Sounds like a simple concept, right?What else specific options we can define, which relates to SPA?Application maintain navigation, history of transitions. And application!, but not browser responsible for linking of all pages (or views in terms of SPA).Whole application fits on a single web page. So we don’t need to refresh the page when user click to some internal link.Persisting important state on the client. Server might know nothing what view are opened on clients side, all such information are stored on client.Fully loaded on the initial page load, and progressively downloads data as required.
  • What is a SPA, (definition from Wikipedia)Sounds like a simple concept, right?What else specific options we can define, which relates to SPA?Application maintain navigation, history of transitions. And application!, but not browser responsible for linking of all pages (or views in terms of SPA).Whole application fits on a single web page. So we don’t need to refresh the page when user click to some internal link.Persisting important state on the client. Server might know nothing what view are opened on clients side, all such information are stored on client.Fully loaded on the initial page load, and progressively downloads data as required.
  • What JavaScript libraries might help for this needs:First of all, it’s jQuery for DOM manipulating, retrieving the views (I mean finding them in DOM) and so on.Knockout.js needs for data binding, and implementation of MVVM patternAmplify.js – this library will help to push data to the services and get information from there, it supports caching, so allows to cache some responses.Breeze.js – useful library which allows us create queries to our data, it’s like a linq for JavaScript. By the way… library also supports caching, but I prefer to use caching on layers which is close to server data services.Sammy.js – maintain navigation based on hash tag after url, and store history of user actions. Quite useful right.We will have a lot of JavaScript code, and will be good to organize it well – require.js will help us. It allows to make componetes with javascript classes, and load them asynchronously.Underscore.js – will help to work with collections of elements, and will be interesting for those, who like functional programming.Toastr.js – to create notifications, popups, error messages on UIQunit – we are professionals, and we cannot believe that our code will work well, we need to prove it by unit tests at least, so, I like qunit library for this.That’s even not all libraries, but this is the most significant one. Others will depends on functional and non-functional requirements to our application.
  • AMD (Asynchronous Module Definition)is a JavaScript API for defining modules and their dependencies in such a way that modules may be asynchronously loadedRevealing Module Patternwe 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.MVVMMVVM facilitates a clear separation of the development of the graphical user interface from the development of the business logic or back end logic known as the model 
  • What is a SPA, (definition from Wikipedia)Sounds like a simple concept, right?What else specific options we can define, which relates to SPA?Application maintain navigation, history of transitions. And application!, but not browser responsible for linking of all pages (or views in terms of SPA).Whole application fits on a single web page. So we don’t need to refresh the page when user click to some internal link.Persisting important state on the client. Server might know nothing what view are opened on clients side, all such information are stored on client.Fully loaded on the initial page load, and progressively downloads data as required.
  • What is a SPA, (definition from Wikipedia)Sounds like a simple concept, right?What else specific options we can define, which relates to SPA?Application maintain navigation, history of transitions. And application!, but not browser responsible for linking of all pages (or views in terms of SPA).Whole application fits on a single web page. So we don’t need to refresh the page when user click to some internal link.Persisting important state on the client. Server might know nothing what view are opened on clients side, all such information are stored on client.Fully loaded on the initial page load, and progressively downloads data as required.
  • What is a SPA, (definition from Wikipedia)Sounds like a simple concept, right?What else specific options we can define, which relates to SPA?Application maintain navigation, history of transitions. And application!, but not browser responsible for linking of all pages (or views in terms of SPA).Whole application fits on a single web page. So we don’t need to refresh the page when user click to some internal link.Persisting important state on the client. Server might know nothing what view are opened on clients side, all such information are stored on client.Fully loaded on the initial page load, and progressively downloads data as required.
  • What is a SPA, (definition from Wikipedia)Sounds like a simple concept, right?What else specific options we can define, which relates to SPA?Application maintain navigation, history of transitions. And application!, but not browser responsible for linking of all pages (or views in terms of SPA).Whole application fits on a single web page. So we don’t need to refresh the page when user click to some internal link.Persisting important state on the client. Server might know nothing what view are opened on clients side, all such information are stored on client.Fully loaded on the initial page load, and progressively downloads data as required.
  • Here is my contacts, please feel free to contact me if you will have any questions according to SPA, or subject that we discussed.I will be glad to discuss different approaches in building SPA.Do you have any questions?
  • 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

    ×