Jasinski Technical Wiki

Navigation

Home Page
Index
All Pages

Quick Search
»
Advanced Search »

Contributor Links

Create a new Page
Administration
File Management
Login/Logout
Your Profile

Other Wiki Sections

Software

PoweredBy

Page History: Angular Walkthrough

Compare Page Revisions



« Older Revision - Back to Page History - Newer Revision »


Page Revision: Wed, Sep 11, 2013, 8:18 AM


Table of Contents [Hide/Show]


   Overview
   Walk-Through
      Initial Setup
      Wiring Up Angular
      Retrieving Data
      Updating Data


Overview

This article walks through the steps to create a simple Angular-based web app.

Walk-Through

Initial Setup

1. Within Visual Studio, create a new app, selecting Web > ASP.NET MVC 4 Web Application. Specify the "Empty" template and the Razor view engine.

2. Add Angular via NuGet: Project > References > Right-Click > Manage NuGet packages > Online > Search for "angular" > Install "Angular JS"

3. Under the website root folder, create a /Scripts/MyAngularApp folder.

4. Within the /Scripts/MyAngularApp folder, create app.js with the following code.

var myAngularApp = angular.module("myAngularApp", ["ngResource"]).
    config(function ($routeProvider) {

        $routeProvider
            .when('/Team', { controller: 'TeamDashboardController', templateUrl: 'AngularTemplates/TeamDashboard.html' })
            .otherwise({ redirectTo: '/Team' });

    });

4. Create the /Views/Shared/_Layout.cshtml file with the following code. The key items are the ng-app attribute on the html tag, and the script references to angular.min.js and app.js.

@{
    Layout = null;
}
<html>
    <head>
        <script src="~/Scripts/angular.min.js"></script>
        <script src="~/Scripts/angular-resource.min.js"></script>
        <script src="/Scripts/MyAngularApp/app.js"></script>
        <script type="text/javascript" src="/Scripts/MyAngularApp/controllers/TeamDashboardController.js"></script>
        @RenderSection("head", required: false)
    </head>
    <body ng-app="myAngularApp">
        <h1>My Angular App</h1>
        @RenderBody()
    </body>
</html>

5. Create a Home controller with an Index method.

6. Create a view for the Home/Index method, specifying a layout file of /Views/Shared/_Layout.cshtml

7. Run your website and verify the /Home/Index page appears as expected. At this point, the site is rather trivial.

Wiring Up Angular

1. Change the code in /Views/Home/Index.cshtml to add the following line of code. The ng-view Angular directive is what triggers Angular to use the routes in app.js

<div ng-view></div>

2. Create the folder /AngularTemplates and add the file TeamDashboard.html with the following content.

<h3>This is the Team Dashboard</h3>

{{ message }}

3. Create the folder /Scripts/MyAngularApp/controllers (this is only for organizational purposes), and a new JavaScript file in it called TeamDashboardController.js with the following content.

'use strict';

myAngularApp.controller('TeamDashboardController', function ($scope) {
    $scope.message = "Hello world!";
});

4. Run your website. At this point you should see two additional lines: "This is the Team Dashboard" and "Hello world!". The latter message is from the message code in TeamDashboard.html.

Retrieving Data

1. Create an Entity Data Model (EDMX) within your project, and point it at the AngularTraining database.

2. Create the folder /Controllers/api, then create a new API controller within it called PersonController with the following code.

public class PersonController : ApiController
{
    [HttpGet]
    public List<AngularTraining.Models.Person> Index()
    {
        using (var db = new AngularTraining.Models.AngularTrainingEntities1())
        {
            return db.People.ToList();
        }
    }

}

3. Within your WebApiConfig.cs file (found within the App_Start folder) change the code for the Register method to the following.

public static void Register(HttpConfiguration config)
{

    config.Routes.MapHttpRoute(
        name: "LookupRoute",
        routeTemplate: "api/{controller}/{action}",
        defaults: new { action = "Index" }
        );

}

4. Create a new folder called /Scripts/MyAngularApp/services and create the file "PersonService.js" within it with the following content.

'use strict';

myAngularApp.factory('PersonService', function ($http, $q) {
  
    return {

        getPeople: function () {

            var url = '/api/person',
                deferred = $q.defer();

            $http.get(url)
                .success(function (data) {
                    deferred.resolve(data);
                })
                .error(function (data, status, headers, config) {
                    deferred.reject();
                });

            return deferred.promise;

        }

    }
});

5. Within the _Layout.cshtml file add a script reference to PersonService.js

@{
    Layout = null;
}
<html>
    <head>
        <script src="~/Scripts/angular.min.js"></script>
        <script src="~/Scripts/angular-resource.min.js"></script>
        <script src="/Scripts/MyAngularApp/app.js"></script>

        <!-- Add the following line -->
        <script src="/Scripts/MyAngularApp/services/PersonService.js"></script>

        <script type="text/javascript" src="/Scripts/MyAngularApp/controllers/TeamDashboardController.js"></script>
        @RenderSection("head", required: false)
    </head>
    <body ng-app="myAngularApp">
        <h1>My Angular App</h1>
        @RenderBody()
    </body>
</html>

6. Within the TeamDashboardController.js file, change your code to call the PersonService

'use strict';

/* Note that [PersonService] was added as an argument after [$scope] */
myAngularApp.controller('TeamDashboardController', function ($scope, PersonService) {
    
    $scope.message = "Hello world!";

    /* Add this service call */
    PersonService.getPeople().then(function (data) {
        $scope.people = data;
    });
});

7. Add the following code to the bottom of your TeamDashboard.html file

<ul>
    <li ng-repeat="person in people">{{person.FirstName}} {{person.LastName}}</li>
</ul>

8. Run your website. You should see a bulleted list of all people in the database.

Updating Data

1. Within your PersonController.cs file, add the PostPerson method, as shown below.

[HttpPost]
public AngularTraining.Models.Person PostPerson(AngularTraining.Models.Person person)
{
    using (var db = new AngularTraining.Models.AngularTrainingEntities1())
    {
        var d = db.People.FirstOrDefault(o => o.PersonID == person.PersonID);

        if (d == null)
        {
            d = new AngularTraining.Models.Person();
            db.People.Add(d);
        }

        d.FirstName = person.FirstName;
        d.LastName = person.LastName;
        d.PhoneNum = person.PhoneNum;

        db.SaveChanges();

        return d;
    }
}

2. Within your PersonService.js file, add the postPerson function as shown below.

'use strict';

myAngularApp.factory('PersonService', function ($http, $q) {
  
    return {

        getPeople: function () {

            var url = '/api/person',
                deferred = $q.defer();

            $http.get(url)
                .success(function (data) {
                    deferred.resolve(data);
                })
                .error(function (data, status, headers, config) {
                    deferred.reject();
                });

            return deferred.promise;

        },

        /*--- Start New Code ---*/  
        postPerson: function (person) {

            var url = '/api/person/postPerson',
                deferred = $q.defer();

            $http.post(url,person)
                .success(function (data) {
                    deferred.resolve(data);
                })
                .error(function (data, status, headers, config) {
                    deferred.reject();
                });

            return deferred.promise;

        }
        /*--- End New Code ---*/

    }
});

3. Within your TeamDashboardController.js file, add the savePerson function, as shown below.

'use strict';

myAngularApp.controller('TeamDashboardController', function ($scope, PersonService) {
    
    $scope.message = "Hello world!";

    PersonService.getPeople().then(function (data) {
        $scope.people = data;
    });

    /*--- Start New Code ---*/
    $scope.savePerson = function (person) {
            
        PersonService.postPerson(person).then(function (data) { alert('Person saved'); });

    }
    /*--- End New Code ---*/

});

4. Within your TeamDashboard.html file, add code to display the names in textboxes with a Save button, as shown below.

<h3>This is the Team Dashboard</h3>

{{ message }}

<ul>
    <li ng-repeat="person in people">{{person.LastName}}, {{person.FirstName}} </li>
</ul>

<!-- Start New Code -->
<div ng-repeat="person in people" style="width:100%">
    <input type="text" ng-model="person.FirstName" /> 
    <input type="text" ng-model="person.LastName" /> 
    <button ng-click="savePerson(person)" >Save</button>
</div>
<!-- End New Code -->

5. Run your website. Notice when you change a name in a textbox, that the "static" text in the bulleted list updates dynamically as you type.

6. When you click a Save button

  • The savePerson(person) function is called. This is defined the $scope variable in your TeamDashboardController.js file

  • The savePerson function calls the PersonService.postPerson(person). An instance PersonService is established via dependency injection in the TeamDashboardController. Within PersonService.js, the postPerson method calls /api/person/postPerson — i.e., the /Controllers/api/PersonController class's PostPerson method, which saves the person object to the database.

  • If the PersonService.postPerson(person) is successful, then the code within PersonService.postPerson(person).then() is called, displaying the user alert.

ScrewTurn Wiki version 3.0.1.400. Some of the icons created by FamFamFam. Except where noted, all contents Copyright © 1999-2024, Patrick Jasinski.