Tips and Tricks in a world of Mix

Posts tagged ‘spa’

AngularJS Fundamentals in 60-ish Minutes

Lecture Summary

http://weblogs.asp.net/dwahlin/archive/2013/04/12/video-tutorial-angularjs-fundamentals-in-60-ish-minutes.aspx

Dan Wahlin

@danwahlin

http://weblogs.asp.net/dwahlin 

 

Demos :

http://tinyurl.com/angularjsdemos

 

http://angularjs.org/

 

image

 

   With the spa the content is loaded from begging and then only refreshes itself with data on the fly by the demand of the user.

   Spa by yourself is hard to connect all the components

image

 

but it’s built in Angular.js rather than using different libraries.

In the Angular framework we have :

image

 

Angularjs – directives , filters and data binding

 

ng-app – directive  <html ng-app>  ( better to write data-ng-app=”” – it’ll be accepted better)

ng-model – <input type=”text” ng-model=”name”>  {{ name }}

property is added to a scope , making an empty viewmodel and filling it with this  property .

{{ name }} – binded data of the model property will be shown on the page

 

<body data-ng-init=”myList=[‘one’, ‘two’]”> – just primitively initiates some list

<li data-ng-repeat=”instance in myList”> {{instance }}</li> loop through all myList

 

Filters

 

 

{{cust.name | uppercase}}

 

 

 

MVVM

 

image

 

 

 

Controller serves the View without knowing anything about the view.

 

image

 

 

 

ng-controller =”SimpleController” connects us.

$scope sent in is the one that carries the data inside.

 

tip- to be explicit with the names of vars and funcs

 

 

 

 

Each Module has some config to define its route.

Routing

            we’ll define view and controller for each route

Factory – will crud data  , not to place in controller  – services , providers , values , resources – access to data

Directives/filters will be placed in View

 

image

 

 

maybe views are divided by device – mobile or desktop

Module is an object container that can hold of : <html ng-app=”moduleName”>

 

image

 

var demoApp = angular.module(‘demoApp’,[]);

(tips – also through angular can get jqLite functionality , jquery Dom manipulation )

Dependency Injection – your module can rely other module to get some data

 

image

 

It’s like a require.js – it’s automatically include the needed modules .

 

Controller in AngularJs = ViewModel

So you can connect your module to a controller and wirte the name of the module in the view

with the ng-app tag naming the module .

You can initialize controller with anonymous function

 

image

 

or you can send an initiated controller

image

 

or you can create a namespace for all controllers , send it in , and the ng-controller attribute will find it in the list of other controllers by the name (this is good way for prototyping) :

 

image

 

 

after that you should put the connection to the controller into the html with a data-ng-controller=”SimpleController” attribute.

 

Routes

 

/view1

/view2

angular only loads the peaces we want by hash

doesn’t reload the whole shell

script template in the shell set / or partials on server

 

 

demoApp.config(function($routeProvider){

               $routeProvider

root:                         .when(‘/’ , ..  {controller: .. , templateUrl:View1.html})

                                 .when (‘partial2’ …

                               

 

templateUrl – it is better to set a folder for templates

 

image

it also handles the history and navigation accordingly

 

 

 

Reuse – Incapsulating code

Get Customers in multiple controllers

Factory – creates object inside the factory and returns it

Service – standard function that uses “this” keyword to define the functions

Provider – $get function that returns the data

Value – getting simple config function. Like  version  and it’s value will be 1.4

 

*Defined Factory can be injected inside some controller -  provides:

               dependency injection

               centralized place for functionality

 

              

image

 

 

Getting data from server by ajax or web sockets

We’ll define the factory/ service/ provider in demoApp

demoApp.factory(‘simpleFactory, function($http){

});

 

we can inject the http angular ajax call request and to perform get , post , put , delete type of calls for restfull type of calls.

in factory you can define a function where you return the object  . that can happen by ajax requst where you shall return a promiss and work in async mode

 

in controller best practice is to init from zero

 

image

 

in controller you can see we’ve sent simpleFactory in .

Than by private function we init the data through the factory.

Custom Directive – animated-view – animation will be activated when you are in the enabled browser.

image

Advertisements

SPA 4–Camper Camper– Surfacing JSON Data with ASP.NET Web API Code – JOHN PAPA

You can check out the series of the posts on the subject

<—SPA 3– Data Models, Entity Framework, and Data Patterns

SPA 5– Code Camper – Web Optimization—>

image

 

image

 

image

image

image

 

Routing

 

image

 

 

image

 

image

image

   1:  

   2: routes.MapHttpRoute( 

   3:  name: 

   4:  ControllerAction, 

   5:  routeTemplate: 

   6:  "api/{controller}/{action}"

   7:  );

 

APIController GET

 

The ApiController offers you an automatic functionality matched to EF UoW structure playing nicely together ! You’’ll most likely create a base with UoW property that will be inherited in every controller .

You can add Json Viewer to Chrome for a better reading.

The Ioc is coming into play when the ICodeCamperUow initializes each controller constructor matched to concrete type of Model Entity.

 

 

We’ve seen the actual class – it sums up the repository interfaces of the whole system

so it will be only one Interface to pass through as a promiss to constructors

   1: public class CodeCamperUow : ICodeCamperUow, IDisposable

   2:   {

   3:       public CodeCamperUow(IRepositoryProvider repositoryProvider)

   4:       {

   5:           CreateDbContext();

   6:  

   7:           repositoryProvider.DbContext = DbContext;

   8:           RepositoryProvider = repositoryProvider;       

   9:       }

  10:  

  11:       // Code Camper repositories

  12:  

  13:       public IRepository<Room> Rooms { get { return GetStandardRepo<Room>(); } }

  14:       public IRepository<TimeSlot> TimeSlots { get { return GetStandardRepo<TimeSlot>(); } }

  15:       public IRepository<Track> Tracks { get { return GetStandardRepo<Track>(); } }

  16:       public ISessionsRepository Sessions { get { return GetRepo<ISessionsRepository>(); } }

  17:       public IPersonsRepository Persons { get { return GetRepo<IPersonsRepository>(); } }

  18:       public IAttendanceRepository Attendance { get { return GetRepo<IAttendanceRepository>(); } }

 

 

Pay attention that the special Repositories For Persons , Sessions and Atrtendace also entered the ICodeCamperUow.

 

Also we could have changed the Implementation to a mock implementation for debugging purposes if needed and we’re getting Disposable at the base.

 

Here we have three classes handling the connectivity and registration of the Model per Interfaces throughout the project.

   1: public class IocConfig

   2:    {

   3:        public static void RegisterIoc(HttpConfiguration config)

   4:        {

   5:            var kernel = new StandardKernel(); // Ninject IoC

   6:  

   7:            // These registrations are "per instance request".

   8:            // See http://blog.bobcravens.com/2010/03/ninject-life-cycle-management-or-scoping/

   9:  

  10:            kernel.Bind<RepositoryFactories>().To<RepositoryFactories>()

  11:                .InSingletonScope();

  12:  

  13:            kernel.Bind<IRepositoryProvider>().To<RepositoryProvider>();

  14:            kernel.Bind<ICodeCamperUow>().To<CodeCamperUow>();

  15:  

  16:            // Tell WebApi how to use our Ninject IoC

  17:            config.DependencyResolver = new NinjectDependencyResolver(kernel);

  18:        }

  19:    }

 

 

Those two are standard development taken by John Papa from Microsoft Dev Team.

   1: public class NinjectDependencyResolver : NinjectDependencyScope, IDependencyResolver

   2:   {

   3:       private IKernel kernel;

   4:  

   5:       public NinjectDependencyResolver(IKernel kernel)

   6:           : base(kernel)

   7:       {

   8:           this.kernel = kernel;

   9:       }

  10:  

  11:       public IDependencyScope BeginScope()

  12:       {

  13:           return new NinjectDependencyScope(kernel.BeginBlock());

  14:       }

  15:   }

 
 
 
   1: public class NinjectDependencyScope : IDependencyScope

   2:     {

   3:         private IResolutionRoot resolver;

   4:  

   5:         internal NinjectDependencyScope(IResolutionRoot resolver)

   6:         {

   7:             Contract.Assert(resolver != null);

   8:  

   9:             this.resolver = resolver;

  10:         }

  11:  

  12:         public void Dispose()

  13:         {

  14:             var disposable = resolver as IDisposable;

  15:             if (disposable != null)

  16:                 disposable.Dispose();

  17:  

  18:             resolver = null;

  19:         }

  20:  

  21:         public object GetService(Type serviceType)

  22:         {

  23:             if (resolver == null)

  24:                 throw new ObjectDisposedException("this", "This scope has already been disposed");

  25:  

  26:             return resolver.TryGet(serviceType);

  27:         }

  28:  

  29:         public IEnumerable<object> GetServices(Type serviceType)

  30:         {

  31:             if (resolver == null)

  32:                 throw new ObjectDisposedException("this", "This scope has already been disposed");

  33:  

  34:             return resolver.GetAll(serviceType);

  35:         }

  36:     }

 

LookupsController –

   1: [ActionName("tracks")]

   2:        public IEnumerable<Track> GetTracks()

You are renaming the functions names to something shorter and easier

 

You can add the right route for it –

image

the trouble is that

   1: routes.MapHttpRoute(

   2:                name: ControllerAndId,

   3:                routeTemplate: "api/{controller}/{id}",

   4:               defaults: new { id = RouteParameter.Optional } 

   5:               

   6:            );

matches any parameter.

 

the most basic route – like call for speakers

   1: // This controller-per-type route is ideal for GetAll calls.

   2:            // It finds the method on the controller using WebAPI conventions

   3:            // The template has no parameters.

   4:            //

   5:            // ex: api/sessionbriefs

   6:            // ex: api/sessions

   7:            // ex: api/persons

   8:            routes.MapHttpRoute(

   9:                name: ControllerOnly,

  10:                routeTemplate: "api/{controller}"

  11:            );

 

we’ll change the original one to match only the digits and another route to match actions specifically , digits parameter only by regex

   1: //  ex: api/sessions/1

   2:           //  ex: api/persons/1

   3:           routes.MapHttpRoute(

   4:               name: ControllerAndId,

   5:               routeTemplate: "api/{controller}/{id}",

   6:               defaults: null, //defaults: new { id = RouteParameter.Optional } //,

   7:               constraints: new { id = @"^\d+$" } // id must be all digits

   8:           );

 

and the last will work with action names that we’ve defined.

   1: // This RPC style route is great for lookups and custom calls

   2:            // It matches the {action} to a method on the controller 

   3:            //

   4:            // ex: api/lookups/all

   5:            // ex: api/lookups/rooms

   6:            routes.MapHttpRoute(

   7:                name: ControllerAction,

   8:                routeTemplate: "api/{controller}/{action}"

   9:            );

 

Attention – John papa has closed the default route of MVC all together.

 

APIController  PUT

image

We can test our put method by fiddler

In fiddler you get the JSON from the Get Method 

http://localhost:52692/api/persons/3

, that in Composer change to the right URI and change the method to PUT 

http://localhost:52692/api/persons

In Request Header we will add the type of the data we send

Content-Type:application/json; charset=utf-8

In the Request Body I’ve just changed Papa to PAPA

 

image

 

When Executed we can see that the data has changed

image

204 code – co content returned as we defined

And the Data changed as I put it in..

 

 

Testing WebAPI Requests with Qunit 

image

 

Qunit – in NuGet it’s “ qunit for ASP.NET MVC

qunit gives you the opportunity to test the Web API , sending and receiving data from client .

It’s a specific testing per every scenario.

  QUnit.testSuites can run all of the tests together which can be very helpful.

 

Testing Model Validation and Other Customization

 

   1: public static class GlobalConfig

   2:     {

   3:         public static void CustomizeConfig(HttpConfiguration config)

   4:         {

   5:             // Remove Xml formatters. This means when we visit an endpoint from a browser,

   6:             // Instead of returning Xml, it will return Json.

   7:             // More information from Dave Ward: http://jpapa.me/P4vdx6

   8:             config.Formatters.Remove(config.Formatters.XmlFormatter);

   9:  

  10:             // Configure json camelCasing per the following post: http://jpapa.me/NqC2HH

  11:             // Here we configure it to write JSON property names with camel casing

  12:             // without changing our server-side data model:

  13:             var json = config.Formatters.JsonFormatter;

  14:             json.SerializerSettings.ContractResolver =

  15:                 new CamelCasePropertyNamesContractResolver();

  16:  

  17:             // Add model validation, globally

  18:             config.Filters.Add(new ValidationActionFilter());

  19:         }

  20:     }

 

json.SerializerSettings.ContractResolver =

    new CamelCasePropertyNamesContractResolver();

will allow to translate the Camel case between server and client so that at client the Upper case won’t be needed.

 

config.Formatters.Remove(config.Formatters.XmlFormatter);

will allow JSON format response.

 

   1: public class ValidationActionFilter : ActionFilterAttribute 

   2:   { 

   3:       public override void OnActionExecuting(HttpActionContext context) 

   4:       { 

   5:           var modelState = context.ModelState; 

   6:           if (!modelState.IsValid) 

   7:           { 

   8:               var errors = new JObject(); 

   9:               foreach (var key in modelState.Keys) 

  10:               { 

  11:                   var state = modelState[key]; 

  12:                   if (state.Errors.Any()) 

  13:                   { 

  14:                       errors[key] = state.Errors.First().ErrorMessage; 

  15:                   } 

  16:               } 

  17:  

  18:               context.Response = context.Request.CreateResponse<JObject>(HttpStatusCode.BadRequest, errors); 

  19:           } 

  20:       } 

  21:   }

  22: }

 

Summary

image

You can check out the series of the posts on the subject

<—SPA 3– Data Models, Entity Framework, and Data Patterns

SPA 5– Code Camper – Web Optimization—>

SPA 6 – SPA Basics – Separating the Ravioli – Code Camper

image

image

You know exactly where one ravioli end and another begins ..

Separation of control

image

Revealing Module Pattern

 

image

Each Module in charge for one thing , and we don’t care how it does it.

An example of dataservice – it’s purpose is to get some person

We have an inner/private function , that will be called dataservice.getPerson()

And we have an external dependency by jQuery ($) also.

 

image

 

 

Solving Modularity with Require.js

Lets assume JavaScript files must be loaded in a specific order – then we can use require..

Separation of Concerns

Define the Dependencies

Load Scripts in the Proper Sequence

image

 

 

define the name of the module , add module dependencies and wright the module logic itself.

image

  • now at the start page reference the require.js
  • add data-main attribute to tell from where you begin the loading , where we have a full list of JavaScript files – kickoff point
  • and require the “alerter” – attention , we didn’t even tell “alerter”anything about dataservice.
  • you can make an alias by paths in requirejs.config  ->  paths:{‘jquery”: “jquery-1.7… “}
  • you can add baseUrl to define the wright folder to look for the js files

 

In Bundles add jQuery and third party libs we load them  from the beginning because we haven’t written them as requirejs requires Smile

So actually we load bundles – jsapplibs and jsmocks – that are connected in main

 

main.js

we could rewrite the thrird party libs or just define them to apply the requirejs convention,  for instance :

define3rdPartyModules();

function define3rdPartyModules() {

       // These are already loaded via bundles. 

       // We define them and put them in the root object.

       define('jquery', [], function () { return root.jQuery; });

       define('ko', [], function () { return root.ko; });

       define('amplify', [], function () { return root.amplify; });

       define('infuser', [], function () { return root.infuser; });

       define('moment', [], function () { return root.moment; });

       define('sammy', [], function () { return root.Sammy; });

       define('toastr', [], function () { return root.toastr; });

       define('underscore', [], function () { return root._; });

   }

 

loadPluginsAndBoot() – extends for other libraries

ko bindingHandlers for instance  – we want to be sure to be loaded only after the third party libraries are loaded.

function loadPluginsAndBoot() {

      // Plugins must be loaded after jQuery and Knockout,

      // since they depend on them.

      requirejs([

              ‘ko.bindingHandlers’,

              ‘ko.debug.helpers’

      ], boot);

  }

the boot from main.js  – running the bootstrapper.js 

 

config.js – repository of information for my app – it’s a constants file , what routes I’m going to support, expirations, throttle and titles, whether I want to use mock or a real data – the global switches ..

 

bootstrapper.js  – dependent on  -> ‘routeConfig’, ‘presenter’, ‘dataprimer’

bootstrapper gives the client the most needed data to upload the app without relaying on WIFI!!

 

dataprimer.js – dependent on –>  ‘ko’, ‘datacontext’, ‘config’

reveiling module pattern – factory for creating a data primer

uses config for logging

datacontext for getting data

ko for binding the data

Summary

image

 

http://jpapa.me/requirejsdemo

Require.js

SPA 2–JOHN PAPA– Technologies and Patterns of the Code Camper SPA

You can check out the series of the posts on the subject

<—SPA 1.1. Getting Code Camper Started

SPA 3– Data Models, Entity Framework, and Data Patterns –>

 

Exploring the Solution Structure

Data Project

  • Global Conventions at the configuration folder ( c# fluent EF definitions)
  • DBContext – in charge for basic CRUD functionality
  • Unit Of Work combining the Repositories and orchestrating it by the process flow as needed.

 

image

 

Model Project – will be returned to client as part of an AJAX request

 

image

 

Web Project  –image

WebApi

  • routing issues connected to global.asax
  • Ninject IOC global configurations
  • bundle for js and css connectivity …and more

image

 

CSS/LESS

LESSLESS extends CSS with dynamic behavior such as variables, mixins , operations and functions.LESS runs on both the server-side (with Node.js and Rhino) or client-side (modern browsers only).

 

Opening the projects –

At the course he’s talking about building it from scratch there he’ll  open MVC4 template with WebApi template because we are going to serve WebApi services which will serve JSON for us,  but we already have the project from my previous post  – Getting Code Camper Started.

Now all we need is is to update the packages thought the NuGet Package Manager Console :

View –> Other Windows –> Package Manager Console

For instance write :

Update-Package jQuery   

It’ll uninstall the old version and install a new one.

After half an hour I’ve discovered the option of just –

Update-Package  which will update all of the packages in your project

 http://nuget.codeplex.com/wikipage?title=Updating%20All%20Packages

now I had all my packages updated at once .

 

I’ve resolved some bizarre issue with critical error on jQuery map and went on .

 

Helpful Tools

You can check out the series of the posts on the subject

<—SPA 1.1. Getting Code Camper Started

SPA 3– Data Models, Entity Framework, and Data Patterns –>

Spa 1 JOHN PAPA – Getting Started with the Code Camper SPA (my summary)

That’s my series of posts on a SPA subject .

Connection to the next post in the series :

                                                               SPA 1.1 – Getting Started with code –>

 

image

wiki – Single-page application

pros :

  • Expected reaction even without wifi
  • Fluid UX Experience
  • Usually with single page load

image

 

Definition of a SPA :

  1. Maintain Navigation ,
  2. Maintain History ,
  3. Deep Linking- when going from page to page it’s not really going to another page, it’s loading a different information on the same page .
  4. Persisting important state on the client  – for instance data that is not likely to be changed (code tables) . Not the whole database but still.
  5. Fully\mostly loaded in the initial page load
  6. Progressively downloads features as required
    Additionally handled issues that we meet in RIA plug-in apps :
  • Async services
  • Client-side application & business logic
  • Long-lived client-side state
  • 2-way data binding (MVVM)
  • Tombstoning /dropped connections – when your app crushes to get back to the point you stopped the last time .

 

    Code Camper overview :

 

  • Using SamiJS for rodding in history feature – allowing to go back and forth in pages
  • Using fade-in on JQuery animation
  • The idea with the star grade for the speaker is to intercept on the transition and check out is it ok to leave the current page or not
  • Tombstone – remembers the uri  and the filters , so even if we close the browser when we come back it’ll open the wright page and the filter that you’ve find before.

 

Technologies of the SPA

image

 

 

Server Technologies

  • DB used SQL CE

 

  • ORM as EF Code First through POCO Models
  • Repositories implementing CRUD (create update delete)  per sessions
  • Unit of Work is the way to aggregate to CRUD data with multiple different Repositories

 

  • Asp.net Web API Exposing the API to the client – interact through Ajax and return JSON.

 

image

 

  • Web Optimization – turn on the minification and bundling for js and css files
  • Ninject IOC  – lets you decouple your classes on the server
  • Json.net

 

 

Client Technology

  • Html5 pros – tags such as section , article , placeholder and a validation attribute
  • Modernizr  – deals with fallbacks, if the browser doesn’t support some HTML5 feature
  • Html5 Boilerplate – gives you the start for developing the HTML5 apps (for instance includes Modernizr in the project )

 

image

 

Javascript Patterns

  • AMD – Resolve our dependencies through our JavaScript modules.

from wiki

Asynchronous module definition (AMD) is a JavaScript API for defining modules such that the module and its dependencies can be asynchronously loaded. It is useful in improving the performance of websites by bypassing synchronous loading of modules along with the rest of the site content.

In addition to loading multiple JavaScript files at runtime, AMD can be used during development to keep JavaScript files encapsulated in many different files. This is similar to other programming languages, for example java, which support keywords such as import, package, and class for this purpose. It is then possible to concatenate and minify all the source JavaScript into one small file used for production deployment.

 

  • Revealing Module Pattern – reveal only the needed parts of the modules publicly
  • Prototypes – improving the performance , reduce some code and save memory space
  • MVVM – model-view-viewmodel –

separate our models – which is our data

and our views  – which are our html

from our viewmodels – which are our JavaScripts

image

 

Libraries

 

image

 

jquery.mockjson – creates a mock data

jquery.activity – can create commands under the ui layer

toastr.js – setting the message throughout the application

 

Connection to the next post in the series :

                                                               SPA 1.1 – Getting Started with code –>

Tag Cloud

%d bloggers like this: