65.9K
CodeProject 正在变化。 阅读更多。
Home

AngularJs 快速入门

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.58/5 (8投票s)

2014年12月3日

CPOL

4分钟阅读

viewsIcon

43682

downloadIcon

842

创建 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 生命周期

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 支持双向数据绑定,视图中的更改会更新模型,模型中的更改会更新视图。

SCOPE - View Model

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>&copy; @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 提供的一些用于模块化和抽象的组件。

© . All rights reserved.