zoukankan      html  css  js  c++  java
  • 2.1:你的第一个AngularJS App

    本章,带你体验一个简单的开发流程,将一个静态的使用模拟数据的应用,变成具有AngularJS特性的动态web应用。在6-8章,作者将展示如何创建一个更复杂,更真实的AngularJS应用。

    1、准备项目

    在项目路径下,新建todo.html,代码如下:

    <!DOCTYPE html>
    <html data-ng-app>
    <head>
    <title>TO DO List</title>
    <link href="bootstrap.css" rel="stylesheet" />
    <link href="bootstrap-theme.css" rel="stylesheet" />
    </head>
    <body>
    <div class="page-header">
    <h1>Adam's To Do List</h1>
    </div>
    <div class="panel">
    <div class="input-group">
    <input class="form-control" />
    <span class="input-group-btn">
    <button class="btn btn-default">Add</button>
    </span>
    </div>
    <table class="table table-striped">
    <thead>
    <tr>
    <th>Description</th>
    <th>Done</th>
    </tr>
    </thead>
    <tbody>
    <tr><td>Buy Flowers</td><td>No</td></tr>
    <tr><td>Get Shoes</td><td>No</td></tr>
    <tr><td>Collect Tickets</td><td>Yes</td></tr>
    <tr><td>Call Joe</td><td>No</td></tr>
    </tbody>
    </table>
    </div>
    </body>
    </html>

    该静态页面已经正常显示。到第六章时,作者会讲应用的文件结构。

    2、使用AngularJS

    用户能用该网页,查看要做的事项的列表,检查事项是否完成,创建一个新的事项。

    2.1、应用AngularJS到HTML文件

    <html ng-app="todoApp">
    <head>
    <title>TO DO List</title>
    <link href="bootstrap.css" rel="stylesheet" />
    <link href="bootstrap-theme.css" rel="stylesheet" />
    <script src="angular.js"></script>
    <script>
    var todoApp = angular.module("todoApp", []);
    </script>
    </head>

            AngularJS apps,从一个或多个模块开始。模块是通过调用angular.module方法创建的,如下面那样:

    var todoApp = angular.module("todoApp", []);

            作者将在第9和第18章描述模块的属性。angular.module方法的参数,是要创建的模块的名字,和模块需要的其他东西的数组。作者创建了一个叫做todoApp的模块。遵循约定,模块的名字以App结尾。因为不需要AngularJS提供其他模块,所以传递空数组作为第二个参数。作者将在第18章,展示不同模块可用的特性。

            作者通过ng-app属性,告诉AngularJS如何应用模块。AngularJS通过给HTML添加新的元素、属性、类和special comments,来扩展HTML,才能工作。AngularJS库动态编译HTML,为了定位和处理这些附加信息,并创建一个应用。你可以通过JavaScript代码,客制化应用的行为,补充内建功能,定义你自己的附加信息到HTML上。

            注意:AngularJS的编译器,不像你碰到的C#或Java项目的编译器那样,处理源代码,为了生成可以执行的运行时输出。精确地说,当浏览器已经加载内容,AngularJS库评估HTML元素,并使用标准DOM API和JavaScript特性,来添加或一处元素,设置事件处理器,等等。在AngularJS开发中,没有明确的变异步骤,只需要修改你的HTML和Javascript文件,并用浏览器加载他们。

            AngularJS附加到HTML上,最重要的就是ng-app属性,它制定该html元素列表包含一个应该被AngularJS编译和处理的模块。当使用的JavaScript框架只有AngularJS时,习惯将ng-app属性应用到html元素。如果你要将AngularJS和其他技术混合,如jQuery,你可以通过在文档上的一个元素上应用ng-app属性,来收缩AngularJS app的边界。

    2.2、给HTML应用AngularJS

    给HTML文档添加一个非标准的属性,看起来很奇怪,特别是如果你已经写过一些web apps,并严格遵守HTML标准。有一个替代方式,使用data属性,给AngularJS添加data-前缀。

    <html data-ng-app="todoApp">

    作者会继续使用AngularJS约定,并使用ng-app属性,和其他HTML增强属性。他建议咱们也这样做。如果你的开发工具不能处理非标准的HTML元素和属性,你也可以不这么做。

    3、创建一个数据模型

    AngularJS支持MVC模式。作者将在第3章讲MVC。简单来讲,遵循MVC模式,需要你把应用分成三个确切的区域:应用中数据(model),对数据的操作逻辑(controllers),显示数据的逻辑(Views)。

    <script>
    var model = {
    user: "Adam",
    items: [{ action: "Buy Flowers", done: false },
    { action: "Get Shoes", done: false },
    { action: "Collect Tickets", done: true },
    { action: "Call Joe", done: false }]
    };
    var todoApp = angular.module("todoApp", []);
    </script>

    提示:作者说,model也可以包含create,load,store,modify数据对象所必须的逻辑。在一个AngularJS应用中,该逻辑一般放在服务器,被web server访问。作者将在第3章详细介绍。

    提示:在任何AngularJS开发项目中,你不得不定义MVC主要部分的作用域。作者保证,在第6章可以看到一个大型的例子。它有很多初始化设置和必须的配置。

    4、创建一个Controller

    Controller定义了业务逻辑,为view提供支持。定义一个controller的最好方法,是解释什么种类的逻辑,是它不支持的,而什么是它支持的。

    逻辑,是处理存储或获取模型的部分数据。逻辑,处理格式化过的数据,将它作为VIEW的一部分,显示给用户。Controller在model和view之间,并连接他们。Controller相应用户交互,更新model中的数据,提供view和view必须的数据。

    作者说,不用担心,本书结束时,你将学会MVC模式,和在AngularJS中应用他们。

    通过调用angular.module返回的模型对象的controller方法,创建一个controller。controller方法的参数,是新controller的名字,和他的功能。

    todoApp.controller("ToDoCtrl", function ($scope) {
    $scope.todo = model;
    });
    </script>
    </head>
    <body ng-controller="ToDoCtrl">

    controller的命名约定,是以Ctrl结尾。

    你不会总是想让views访问整个model,所以你希望使用controller,来明确地选择一部分数据,这叫做scope(范围)。

    我的controller函数的参数,调用了$scope,这就是说,$符号跟随者单词scope。在AngularJS app中,以$开始的变量名,表示是AngularJS提供的内建特性。当你看到$符号,它一般指向一个内建的服务,它是一个自包含的组建,为多个控制器提供特性。但$scope很特别,它用于曝露数据和函数给view。作者将在第13章讲解scope,在18-25章讲解内建services。

    对于本应用而言,作者系统它在view中使用整个model,所以他定义了一个属性,在$scope服务对象上,调用todo,并像下面那样,指派完整的model:

     

    $scope.todo = model;

    作者也不得不指定controller负责的html文档的区域。因为是一个简单的应用,并且只有一个controller,作者就在body元素上应用ng-controller。

     

    <body ng-controller="ToDoCtrl">

    ng-controller属性的值,是要设置的controller的名字。作者将在第13章深入controller的主题。

    4、创建一个View

    作者将在下面的代码中,演示如何使用一种注释类型,也叫做数据绑定。

     

    <h1>
    {{todo.user}}'s To Do List
    <span class="label label-default">{{todo.items.length}}</span>
    </h1>
    
    <tbody>
    <tr ng-repeat="item in todo.items">
    <td>{{item.action}}</td>
    <td>{{item.done}}</td>
    </tr>
    </tbody>
    5、插入Model View
    AngularJS使用双花括号{{}},来代表一个数据绑定表达式。表达式的内容,
    作为JavaScript,被求值,通过使用Controller,来限制数据和功能被分配给scope。
    在本例中,作者只能访问它在定义controller时,使用在$scope对象创建的属性名,来访问指派给$scope对象的那部分数据。
    这意味着,例如,如果作者想访问model.user属性,作者定义一个数据绑定表达式,
    引用todo.user。这就是为什么,作者给$scope.todo属性指派model对象。
        AngularJS编译文档中的HTML,发现ng-controller属性,让ToDoCtrl函数设置用于创建view的范围。遇到的每个数据绑定表达式,AngularJS在$scope对象中查找指定的值,
    并添加该值到HTML文档。例如,下面的例子:

     

    {{todo.user}}'s To Do List

    它会被处理,并翻译为下面的字符串:

    Adam's To Do List

    这就是所谓的数据绑定或模型绑定,model中的值,绑定到一个html元素的内容上。这里有一些不同的方式来创建数据绑定,作者将在第10章解释。

    6、求表达式的值

    一个数据绑定表达式的内容,可以是任何可用的JavaScript声明,意味着你能执行操作,从model中创建新的数据。下面是显示to-do items的个数:

    <div class="page-header">
    {{todo.user}}'s To Do List<span class="label label-default">{{todo.items.length}}</span>
    </div>

    提示:在表达式中,应该只执行简单的操作。不要使用数据绑定,来执行复杂逻辑或对model的操作。这应该是controller的工作。你会经常遇到很难讲逻辑归类于view或controller的情况。作者的建议是,不要担心它。以最快的速度开发,再以后需要时再移动这些逻辑。如果实在不知道该怎么做,就把逻辑放在controller中,它有60%的几率是正确的。

    7、使用指令

    表达式中也可以使用指令,这会告诉AngularJS,你想要怎么处理内容。在本课中,作者使用ng-repeat属性。

    <tr ng-repeat="item in todo.items">
    <td>{{item.action}}</td><td>{{item.done}}</td>
    </tr>

    它会产生下面的代码

    <tr ng-repeat="item in todo.items" class="ng-scope">
    <td class="ng-binding">Buy Flowers</td>
    <td class="ng-binding">false</td>
    </tr>
    <tr ng-repeat="item in todo.items" class="ng-scope">
    <td class="ng-binding">Get Shoes</td>
    <td class="ng-binding">false</td>
    </tr>
    <tr ng-repeat="item in todo.items" class="ng-scope">
    <td class="ng-binding">Collect Tickets</td>
    <td class="ng-binding">true</td>
    </tr>
    <tr ng-repeat="item in todo.items" class="ng-scope">
    <td class="ng-binding">Call Joe</td>
    <td class="ng-binding">false</td>
    </tr>

    ng-repeat指令,会是你最常用的指令之一。

    8、超越基本

    8.1使用双向模型绑定

    作者之前使用的绑定,都是单向绑定,从model中取出值,用于在模板中分发这些元素。这是一个相当基本的材料,并且在web app开发中,广泛使用的技术。例如,作者在使用jQeury时,经常使用Handlebars模板包,它提供该类型的绑定,对从数据对象生成HTML内容很有用。

    AngularJS也提供双向绑定,用模型生成元素,当元素改变时,导致模型也相应的改变。

    <tr ng-repeat="item in todo.items">
    <td>{{item.action}}</td>
    <td><input type="checkbox" ng-model="item.done" /></td>
    <td>{{item.done}}</td>
    </tr>

    作者添加了一个checkbox input元素。重要的附加信息,是ng-model属性,它告诉AngularJS,在input元素的值和相应数据对象的done属性之间,创建一个双向绑定。

             当HTML第一次编译,AngularJS会使用done属性的value,设置input元素的value。

            AngularJS的绑定是动态的,双向的绑定。两个元素绑定到同一个,一个元素变了,另一个也会变。

            双向绑定,可以应用于用户输入的元素,生成使用HTML表单元素关联的有意义的元素。作者会在第12章深度讲解。

    8.2、创建并使用控制器行为

    控制器在范围上定义行为。行为,是操作model上的数据,以实现应用中的业务逻辑的功能。行为,通过controller定义,支持一个view,以显示数据,并基于用户交互更新模型。

    todoApp.controller("ToDoCtrl", function ($scope) {
    $scope.todo = model;
    $scope.incompleteCount = function () {
    var count = 0;
    angular.forEach($scope.todo.items, function (item) {
    if (!item.done) { count++ }
    });
    return count;
    }
    });
    
    
    <div class="page-header">
    <h1>
    {{todo.user}}'s To Do List
    <span class="label label-default" ng-hide="incompleteCount() == 0">
    {{incompleteCount()}}
    </span>
    </h1>
    </div>

    通过给传递给controller 函数的$scope对象添加功能,来定义行为。

    提示:作者使用angular.forEach方法,来枚举数组的内容。AngularJS包含许多有用的工具方法,补充JavaScript语言。作者将在第4章描述这些工具方法。

    附加在$scope对象上的属性名,作为行为的名字。作者的行为叫做incompleteCount,可以在ng-countroller属性的范围内,调用他。

    ng-hide指令的表达式为true时,会隐藏元素。

    提示:ng-hide是基于AngularJS model状态自动操作DOM的大量指令中的一个。作者会在第11章详细讲解,并在15-17章教咱们如何创建自己的指令。

    8.3、使用其他行为

    $scope.warningLevel = function () {
    return $scope.incompleteCount() < 3 ? "label-success" : "label-warning";
    }<div class="page-header">
    <h1>
    {{todo.user}}'s To Do List
    <span class="label label-default" ng-class="warningLevel()"
    ng-hide="incompleteCount() == 0">
    {{incompleteCount()}}
    </span>
    </h1>
    </div>

    作者定义了一个叫做warningLevel的行为,它基于完成的to-do items的个数,返回Bootstrap CSS class的名字。

    8.4相应用户交互

    你已经看到如何将行为和指令结合在一起,创建app 特性,这种结合,将派生许多AngularJS app的功能。一个最强大的结合,是实现响应用户的交互。

    $scope.addNewItem = function (actionText) {
    $scope.todo.items.push({ action: actionText, done: false });
    }
    
    
    <div class="input-group">
    <input class="form-control" ng-model="actionText" />
    <span class="input-group-btn">
    <button class="btn btn-default"
    ng-click="addNewItem(actionText)">Add</button>
    </span>
    </div>

    作者添加了一个叫做addNewItem的行为,它持有一个新to-do item的文本,并添加一个对象到数据模型,使用该文本作为action属性的值,并设置done属性为false。

    这是作者展示的第一个修改model的行为。注意,该行为依然作为一个标准的Javascript函数被定义。

    ng-click指令,这只一个处理器,当click事件被处罚,计算表达式的值。在本例中,表达式指向addNewItem行为,传递动态actionText属性作为参数。

    8.5过滤和排序模型数据

    在第14章,作者介绍了AngularJS过滤特性。

    <tr ng-repeat="item in todo.items | filter:{done: false}
     | orderBy:'action'">
    <td>{{item.action}}</td>
    <td><input type="checkbox" ng-model="item.done" /></td>
    </tr>

    过滤可以应用到数据模型的任何部分。

    提示:作者在orderBy里,使用字符串,作为属性值。使用’‘单引号。默认地,AngularJS假设scope定义的任何东西都是一个属性,并且不用引号,会查找一个叫做action的scope属性。这在你以编程的方式定义值时,会很有用。但是不意味着你不得不记住使用字符值,当你想要制定一个常熟。

    model中的数据并没有被排序,排序操作时在ng-repeat指令用于执行创建table的row时,执行的。

    8.6、改善过滤器

    todoApp.filter("checkedItems", function () {
    return function (items, showComplete) {
    var resultArr = [];
    angular.forEach(items, function (item) {
    if (item.done == false || showComplete == true) {
    resultArr.push(item);
    }
    });
    return resultArr;
    }
    });

    该过滤方法创建了一个过滤fatory,它返回一个功能,用于过滤一组数据对象。items参数,由AngularJS提供,是一组要被过滤的对象。当作者应用过滤器时,他会为showComplete参数提供一个值,它用于表明,是否显示已经完成的人物。

    <tbody>
    <tr ng-repeat=
    "item in todo.items | checkedItems:showComplete | orderBy:'action'">
    <td>{{item.action}}</td>
    <td><input type="checkbox" ng-model="item.done" /></td>
    </tr>
    </tbody>
    </table>
    <div class="checkbox-inline">
    <label><input type="checkbox" ng_model="showComplete">
     Show Complete</label>
    </div>

    这个自定义的过滤器,和内建的过滤器一样。我使用filter作为过滤器的方法名,使用一个:,后面跟随一个我想要传递给过滤器函数的模型属性名。

    8.7通过Ajax获取数据

    作者将在第五章讲解JSON。创建一个todo.json文件,内容如下:

    [{ "action": "Buy Flowers", "done": false },
    { "action": "Get Shoes", "done": false },
    { "action": "Collect Tickets", "done": true },
    { "action": "Call Joe", "done": false }]
    <PRE><SPAN style="COLOR: #000000">var model = {
    user: "Adam"
    };
    var todoApp = angular.module("todoApp", []);
    todoApp.run(function ($http) {
    $http.get("todo.json").success(function (data) {
    model.items = data;
    });
    });</SPAN></PRE>

    调用AngularJS模块对象定义的run方法,该方法执行一个函数,它只有AngularJS已经执行初始化设置后执行一次,用于one-off任务。

    我制定$http,作为传递给run方法的函数的参数,它告诉AngularJS,我想要使用为Ajax调用提供支持的服务对象。使用参数告诉AngularJS,你需要哪个特性,这叫做依赖注入。作者将在第9章介绍。

    $http服务提供访问低级Ajax请求。低级在本例中,并不低。除非和$resources服务作比较。该服务用于和RESTful web services互动。作者将在第3章讲REST,在第12章讲$resource。作者使用$http.get方法,做了一个HTTP GET请求,从服务要todo.json文件。

    get方法的结果,是一个许诺,他是一个对象。作者会在第5章讲解,在第20章深入讲解。在许诺对象上,调用success方法,当Ajax请求完成时,JSON数据从服务端返回,转换为一个Javascript对象,传递到作者的success函数作为data参数。作者使用收到的数据,更新模型。

  • 相关阅读:
    XCode Playground Overview
    Swift开发学习(二):Playground
    swift网址
    swift关于is和as的解释
    Swift之 ? 和 !
    Swift 学习之二十一:?和 !(详解)
    Swift学习三
    Makefile project
    20171110面试笔记 服务器端程序员+C/C++开发
    关键字
  • 原文地址:https://www.cnblogs.com/msdynax/p/3783052.html
Copyright © 2011-2022 走看看