AngularJs 快速入门






4.58/5 (8投票s)
创建 AngularJS 应用程序的快速入门教程。
引言
我们将开发一个基本的 AngularJS 应用程序,其中将涵盖以下教程。
- AngularJS 基础知识
- 路由
- 使用其语法
- 与数据服务交互
资源AngularJS 库可以从 https://angularjs.org/ 下载。
教程可以在 https://builtwith.angularjs.org 找到
本教程的目的将使用 VS 2012,.NET MVC 模板。
AngularJS 是一个完全客户端的 SPA(单页应用程序)MV* 框架,它在 DOM 完全加载后开始运行,类似于 JQuery 等其他客户端库。它具有以下主要组件:
- 用于构建健壮的以客户端为中心的应用程序的“SPA”框架
- 测试 – 端到端集成,单元测试
- 双向数据绑定,模板构建,声明式 UI
- 视图,控制器,作用域
- 依赖注入,指令,过滤器
- 模块和路由
背景
掌握基本的 JavaScript,对象字面量表示法。
AngularJS 在加载完整 DOM 后开始执行,然后找到各种数据点并用数据替换它们。下图解释了 Angular 应用程序的生命周期。

AngularJS 是一个具有以下组件的框架:

Using the Code
要设置 AngularJS 应用程序,您只需要一个 Web 服务器来提供您的页面和 AngularJS 库。
本文将包含以下 AngularJs 组件的代码:
- 服务 - 用作查询数据的辅助函数
- 控制器 - 用于提供数据和编写业务逻辑
- 视图 - 用于呈现信息
- 过滤器 - 用作格式化数据的辅助方法
服务器/编辑器
有不同的编辑器可以用来构建您的应用程序并充当服务器,例如 Yeoman、Lineman、Visual Studio。
配置应用程序
那么让我们开始编写代码。我将使用 Visual Studio 作为开发 IDE,其 MVC 基础模板来构建代码结构。
因此,AngularJs 在正常运行、路由、数据服务交互等方面使用一组 JS 文件。
一旦您设置了一个空的 MVC 模板,请将文件放在您的主/布局页面中,以便每个继承此布局页面的视图都可以使用它们。
 
           
代码
执行从包含路由逻辑的 *app.js* 文件开始。
路由以从特定到通用的模式定义如下:
.when('<Url>',{
templateUrl: '<ViewPath To Load>',
controller: '<ControllerName To Use for View>'
})
app.js 文件
//angular.module("<moduleName>", [<Dependencies>]);
var appModule = angular.module("appModule", ['ngRoute', 'demoControllers']);
appModule.config(['$routeProvider', function ($routeProvider) {
    $routeProvider.
    when('/user', {
        templateUrl: 'Content/NgUser.html',
        controller: 'UserController'
    }).
      when('/user/:userId', {
          //userId - variable from URL
          templateUrl: 'Content/NgUserDetail.html',
          controller: 'MessageController'
      }).
    when('/message/:messageId', {
        templateUrl: 'Content/NgMessageDetails.html',
        controller: 'MessageDetailController'
    }).
      otherwise({
          redirectTo: '/user'
      });
}]);
服务
由于 AngularJS 是一个客户端 JavaScript 框架,它主要依赖于 JSON 格式的数据。它内置了从远程或本地服务提供商获取数据的抽象,例如 `\@http`,类似于 JQuery 中的 `$.ajax` 函数。
services.js 文件
var demoServices = angular.module("demoServices", []);
demoServices.factory("UserService", ["$http", "$q", function ($http, $q) {
    var serv = {};
    // Return public API.
    return ({
        GetAllUsers: GetAllUsers,
        GetUserDetail: GetUserDetail
    });
    function GetAllUsers() {
        //var req = $http.get('/service/getusers');
        var req = $http({
            method: "get",
            url: "/service/getusers"
            //params goes in url as query string
            //params: {
            //    id: id
            //},
            //data goes in the request body
            //For Post Body Parameters
            //data: {
            //    id: id
            //}
        });
        return req.then(handleSuccess, handleError);
    }
    function GetUserDetail(id) {
        //var req = $http.get('/service/GetUserDetail', params:{ "id" : id});
        var req = $http({
            method: "get",
            url: "/service/GetUserDetail",
            params: {
                id: id
            }
        });
        return req.then(handleSuccess, handleError);
    }
    // ---
    // PRIVATE METHODS.
    // ---
    // I transform the error response, unwrapping the application data from
    // the API response payload.
    function handleError(response) {
        // The API response from the server should be returned in a
        // nomralized format. However, if the request was not handled by the
        // server (or what not handles properly - ex. server error), then we
        // may have to normalize it on our end, as best we can.
        if (
            !angular.isObject(response.data) ||
            !response.data.message
            ) {
            return ($q.reject("An unknown error occurred."));
        }
        // Otherwise, use expected error message.
        //return ($q.reject(response.data.message));
        return ($q.reject("hagjhsaggjasjgjagdj error"));
    }
    // I transform the successful response, unwrapping the application data
    // from the API response payload.
    function handleSuccess(response) {
        return (response.data);
    }
}]);
控制器
控制器是编写业务逻辑并将数据绑定到模型以供视图使用的地方。
每个控制器都注入(由 AJs 框架进行依赖注入)一个 `$scope` 对象,该对象包含数据(属性、对象和函数)。
`Scope(ViewModel)` 是 `Controller` 和 `View` 之间的粘合剂。它将数据从控制器传递到视图,再从视图传递回控制器。AngularJS 支持双向数据绑定,视图中的更改会更新模型,模型中的更改会更新视图。


controllers.js 文件
var demoControllers = angular.module("demoControllers", ['demoServices', 'demoFilters']);
demoControllers.controller("HomeController", ["$scope", "$http", function ($scope, $http) {
    $scope.pageHeading = 'this is page title.';
    $http.get('/service/getmessages')
        .success(function (data) {
            $scope.messages = data;
        })
    .error(function () {
        alert("some error");
    });
}]);
demoControllers.controller("UserController", ["$scope", "UserService", function ($scope, UserService) {
    $scope.pageHeading = 'behold the majesty of your page title';
    //$scope.users = User.query();
    UserService.GetAllUsers().then(function (data) {
        $scope.users = data;
    });
    UserService.GetUserDetail(2).then(
         function (data) {
             $scope.users.push(data);
         });
    $scope.AddUser = function () {
        /*
        var newUserName = $scope.newUser.name;
        if (newUserName.indexOf(" ") != -1) {
            alert("invalid " + newUserName.indexOf(" "));
        }
        */
        console.log($scope.newUser.name);
        console.log($scope.newUser.email);
        alert("User Added");
        //service call to save newly added user to db
        $scope.users.push({ name: $scope.newUser.name, email: $scope.newUser.email });
        $scope.newUser.name = "";
        $scope.newUser.email = "";
    }
}]);
视图
视图包含表示逻辑和用于插入控制器 `$scope` 模型中的数据的数据点。
{{<variable here>}}
Angular 会查找上述符号,并用 `$scope` 中同名变量的数据替换它们。
例如:
<code>Controller: ($scope.username = “Scott”;)
View:       {{ username }}. 
Output:     Scott.</code>
还存在各种其他指令,例如:
- `ng-view`: Angular 根据路由在包含此属性的元素内的对应视图中的数据进行替换。此属性用于站点的母版页。
- `ng-app`: 用于为 HTML 块定义模块。
- `ng-repeat`: 类似 `foreach` 地重复元素。
- `ng-click`: 定义 `onClick` 元素时要调用的函数。
- `ng-model`: 对模型变量进行双向数据绑定。如果不存在则创建。例如:`ng-model="newUser.name"` - 它创建一个变量并显示其值在元素中。
- `ng-controller`: 为 HTML 中的作用域定义一个控制器。
母版页 (_Layout.cshtml)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <title>AngularJS Application</title>
    <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
    <meta name="viewport" content="width=device-width" />
    @Styles.Render("~/Content/css")
    @Scripts.Render("~/bundles/modernizr")
    @Scripts.Render("~/bundles/jquery")
    <script src="~/Scripts/Angular/angular/angular.min.js"></script>
    <script src="~/Scripts/Angular/angular-route/angular-route.min.js"></script>
    <script src="~/Scripts/Angular/angular-resource/angular-resource.min.js"></script>
    <script src="~/Scripts/App/app.js"></script>
    <script src="~/Scripts/App/controllers.js"></script>
    <script src="~/Scripts/App/filters.js"></script>
    <script src="~/Scripts/App/services.js"></script>
</head>
<body>
    <header>
    </header>
    <div id="body" ng-app="appModule">
        <section class="content-wrapper main-content clear-fix" ng-view>
            @RenderBody()
        </section>
    </div>
    <footer>
        <div class="content-wrapper">
            <div class="float-left">
                <p>© @DateTime.Now.Year - My ASP.NET MVC Application</p>
            </div>
        </div>
    </footer>
    @RenderSection("scripts", required: false)
</body>
</html>
母版页中的 `ng-view` 属性。
NgUser.html 文件
Hello
<a href="#/user/">User</a>
<div class="bar">User List</div>
<div ng-repeat="us in users" style="padding: 10px;">
    <a style="text-decoration: none;" href="#/user/{{us.name}}">
        <b>{{$index + 1}}. </b>{{us.name}}, {{us.email}}
    </a>
</div>
<div class="bar">Add A User</div>
<form name="addUserForm">
    <input placeholder="username" type="text" 
    name="fullname" value=" " ng-model="newUser.name" required />
    <input placeholder="email" type="email" 
    name="email" value=" " ng-model="newUser.email" required />
    <button ng-click="AddUser()" 
    ng-disabled="!addUserForm.$valid">Click To Add User</button>
</form>
<div ng-controller="TempController">
    {{pageMessage}}
    Test - {{pageHeading}}
</div>
<script>
    $(function () {
    });
</script>
HTML 表单的工作方式与 HTML 的常规结构类似,只是在提交按钮 `onClick` 时,会调用一个函数(此处为 `AddUser()`),该函数负责验证和保存数据。
过滤器。
过滤器用于在视图中呈现的数据的修改/格式化。
filters.js 文件
var demoFilters = angular.module("demoFilters", []);
demoFilters.filter("titleCase", function () {
    var titleCaseFilt = function (input) {
        var wordsInInput = input.split(' ');
        for (var i = 0; i < wordsInInput.length; i++) {
            wordsInInput[i] = wordsInInput[i].charAt(0).toUpperCase() + wordsInInput[i].slice(1);
        }
        return wordsInInput.join(' ');
    };
    return titleCaseFilt;
});
demoFilters.filter("searchForFilter", function () {
    // All filters must return a function. The first parameter
    // is the data that is to be filtered, and the second is an
    // argument that may be passed with a colon (searchFor:searchString)
    return function (arr, searchForText) {
        if (!searchForText) {
            return arr;
        }
        var result = [];
        searchForText = searchForText.toLowerCase();
        // Using the forEach helper method to loop through the OBJECTS array
        angular.forEach(arr, function (item) {
            //sender, body, subject
            if (item &&
                (item.sender
                && item.sender.toString().toLowerCase().indexOf(searchForText) !== -1)
                ||
                (item.body
                && item.body.toString().toLowerCase().indexOf(searchForText) !== -1)
                ||
                (item.subject
                && item.subject.toString().toLowerCase().indexOf(searchForText) !== -1)
                ) {
                result.push(item);
            }
        });
        return result;
    };
});
摘要
因此,在本文中,我们探讨了如何在 AngularJS 中开发一个示例应用程序。我们还研究了 Angular 提供的一些用于模块化和抽象的组件。


