SPA (Single Page Application) in MVC 5 and AngularJS

This article describes about the SPA (Single Page Application) in MVC5 using AngularJS. Angular is a JavaScript frame work and has a powerful data binding mechanism.

Here, we explore on below items.
• Set up MVC5 application with angular
• Angular routing for SPA
• Angular view binding
• Handle Layout page and Content page with Angular bindings and routing.

If you are new to the angular, please visit below link for basics.
http://www.w3schools.com/angular/

Create a new Asp.Net Web Application by selecting the MVC template and add install the Angular Core and Angular Route packages from NuGet as below.

As MVC application is created with jQuery by default, there is a possibility of getting conflict while referencing angular scripts and using jQuery plugins. So, follow the sequence while referencing jQuery and angular, as first reference add the jQuery scripts and then follows angular scripts as below.

As this is a MVC application, add the scripts to Bundle.Config which is under App_Start folder for bundling and minification.
bundles.Add(
               new ScriptBundle("~/bundles/angularspa").Include(
                   "~/Scripts/jquery-{version}.js",
                   "~/Scripts/jquery-ui.js",
                   "~/Scripts/respond.js",
                   "~/Scripts/bootstrap.js",
                   "~/Scripts/angular.js",
                   "~/Scripts/angular-route.js"
  ));

Reference this script bundle in Layout.cshtml under <Head> </Head>.
@Scripts.Render("~/bundles/angularspa");

Define the Angular module name; here module represents the app name. Under the module, you will have controllers. Each controller will be associated with the respective view. Here, the controller represents the view model in WPF where you define/assign the properties and bind them in html view.

Add a new script file as app.js and create an angular module as below.
var app = angular.module('angularspa', ["ngRoute"]);

From above, named the module as “angularspa” and added the directive “ngRoute” to support routing.
Use the module name in Layout.cshtml  as ng-app which is an angular property to represent the angular module name.

<body ng-app="angularspa" >

Add a new script file as rootController.js and create a angular controller as below.
app.controller('rootController', ["$scope", "$http", "$rootScope", function ($scope, $http, $rootScope) {
    $scope.home = 'Home';
    $scope.contact = 'Contact';
    $scope.about = 'About';
}]);

Here, named the controller as rootController, $scope is a binding part between view (html) and controller (javascript) and is a object with properties and methods.
$http, used to make API/service calls (Get, Post).
$rootScope, to define the global properties and will be accessed in any of the controller or views within the scope of defined module.
As Layout page is a shared and common across all the content pages, use the rootController for bindings in Layout page.
<body ng-app="angularspa" ng-controller="rootController">

Here, define the menus for navigation from layout page and bind the menu titles from controller as below.
             <ul class="nav navbar-nav">
                     <li><a href="/Home">{{home}}</a></li>
                     <li><a href="/About">{{about}}</a></li>
                     <li><a href="/Contact">{{contact}}</li>
                 </ul>

For each anchor element, added the href for navigation. For example, uri  “/Home” should be navigated to the Home view when clicks on the Home menu. This navigation mechanism is accomplished by angular routing.

When you run MVC application, routing will be handled by route.config and loads the index page as a default. Exactly, this is the page where we invoke the angular route and loads the respective views.

Use ng-view property in index view to load the html views dynamically from routing as below.
<div class="text-center">
    <div class="row" ng-view>
    </div>
</div>

Add a new js file as route.js and define the routing with routeProvider as below.

app.config(['$routeProvider', '$locationProvider', function ($routeProvider, $locationProvider) {
    var baseUrl = $("base").first().attr("href");
    console.log("base url for relative links = " + baseUrl);
    $routeProvider
         .when('/Home', {
            templateUrl: baseUrl + 'Home/Home',
            controller: 'homeController'
        })
         .when('/Contact', {
            templateUrl: baseUrl + 'Home/Contact',
            controller: 'contactController'
        })
           .when('/About', {
              templateUrl: baseUrl + 'Home/About',
              controller: 'aboutController'
          })
    .otherwise({
        redirectTo: '/Home'
    });

    $locationProvider.html5Mode(true);
}]);

From above, when route is “/Home”,   load Home view from Home folder and associate the homeController.js for bindings. As similar defined the routes for all the views.
Reading the basrUrl and appending to the templateUrl to work the routing even when you deploy the app
Use the $locationProvider to configure how the application deep linking paths are stored. If you set html5Mode to true removes # in browser url.


Make sure to add these controller scripts files too in script bundle, complete piece of code as below.
bundles.Add(
               new ScriptBundle("~/bundles/angularspa").Include(
                   "~/Scripts/jquery-{version}.js",
                   "~/Scripts/jquery-ui.js",
                   "~/Scripts/respond.js",
                   "~/Scripts/bootstrap.js",
                   "~/Scripts/angular.js",
                   "~/Scripts/angular-route.js",
                   "~/Scripts/angular/app.js",
                     "~/Scripts/angular/route.js",
                     "~/Scripts/angular/rootController.js",
                     "~/Scripts/angular/homeController.js",
                       "~/Scripts/angular/contactController.js",
                       "~/Scripts/angular/aboutController.js"
                   ));

Download the complete solution from below link. Removed the packages due to size constraint. Make sure to add missing packages before building the solution.

http://nullskull.com/FileUpload/-407123783_AngularSpa.zip    

By Siva Jagan Dhulipalla   Popularity  (1156 Views)