素材巴巴 > 程序开发 >

《AngularJS高级程序设计》——2.2 使用AngularJS

程序开发 2023-09-07 11:17:42

本节书摘来自异步社区《AngularJS高级程序设计》一书中的第2章,第2.2节,作者:【美】Adam Freeman(弗里曼)著,更多章节内容可以访问云栖社区“异步社区”公众号查看

2.2 使用AngularJS

对于要创建的基本功能来说,todo.html文件中的静态HTML目前仅作为占位符使用。用户应该能看到待办事项的列表,勾选掉已完成的事项,并创建新事项。在下面各节中,我打算将AngularJS加进来,并应用一些基本特性来为我的待办事项应用赋予生命。简单起见,假定只有一个用户,并且不用考虑保留应用程序中的数据状态。
2.2.1 将AngularJS应用到HTML文件
将AngularJS加入到HTML文件中是挺简单的,只需简单增加一个script元素来引入angular.js文件,创建一个AngularJS模块,并对html元素应用一个属性即可,如清单2-2所示。
清单2-2 在todo.html文件中创建和使用一个AngularJS模块
screenshot
AngularJS应用由一个或多个模块组成。模块是由调用angular.module方法而创建的,如下:
screenshot
我将在第9章和第18章中适当地介绍模块,但是你可以从清单2-2中看到我是如何为该实例创建并使用一个模块的。传给angular.module方法的参数是要创建的模块名以及一个由所需要的其他模块构成的数组。我创建了一个名为todoApp的模块,遵循了那个让人有点困惑的将App附加到模块名称后面的惯用法,并通过将空数组传给第二个参数来告诉AngularJS不再需要其他模块。(某些AngularJS特性在其他不同的模块中可用,在第18章中还将演示如何创建自己的模块。)
我通过ng-app属性告诉AngularJS如何使用这个模块。AngularJS通过增加新元素、属性、CSS类和特殊注释(虽然鲜有使用)的方法来扩展HTML,完成工作。AngularJS库动态地编译一个文档中的HTML,以定位和处理这些附加品,并创建应用程序。你可以使用JavaScript代码对内置功能进行补充,定制应用程序的行为,并定义自己向HTML的附加品。
AngularJS对HTML的最重要的附加品是ng-app属性,该属性指定了清单中的html元素包含一个应当被AngularJS编译和处理的模块。当AngularJS是唯一被使用的JavaScript框架时,惯例是对html元素使用ng-app属性,就像我在清单2-2中所做的那样。如果你在将AngularJS与其他技术如jQuery混用,你可以通过将ng-app属性使用到文档里的某个元素来缩小AngularJS应用的边界。
2.2.2 创建数据模型
AngularJS支持模型-视图-控制器(MVC)模式,在第3章中我将加以介绍。简而言之,遵循MVC模式需要你将应用程序分成三部分不同的区域:程序中的数据(模型)、对数据进行操作的逻辑(控制器),以及显示数据的逻辑(视图)。

在我的待办事项程序中的数据现在分布在各个HTML元素之间。用户名包含在header中,如下:
screenshot

待办事项项目的细节包含在表格中的td元素里,如下:
screenshot

我的第一个任务就是将所有数据放到一起,并将数据从HTML元素中分离出来,以便创建一个模型。从对用户的表现形式中分离数据是MVC模式的关键点之一,正如我在第3章中将解释的。因为AngularJS程序存在于浏览器中,我需要使用一个script元素中的JavaScript来定义我的数据模型,如清单2-3所示。

清单2-3 在todo.html文件中创建一个数据模型
screenshot
我定义了一个名为model的JavaScript对象,具有与分布在各个HTML元素中的数据相对应的属性。user属性定义了用户名,items属性定义了一个对象数组,描述了各个待办事项。

通常在定义一个模型时,不需要同时定义MVC模式的其他部分,但是我想演示如何搭建这个简单的AngularJS程序,所以也同时定义了其他部分。在图2-2中可以看到这一修改带来的变化。
screenshot
2.2.3 创建控制器
控制器定义了用于支持视图的业务逻辑,尽管业务逻辑这一术语并不是很有用。描述控制器的最好的方式是解释清楚它不应包含什么样的逻辑,以及控制器中剩下了哪些逻辑。

处理存储或读取数据的逻辑是模型的一部分。处理将数据格式化并显示给用户的逻辑是视图的一部分。控制器位于模型和视图之间并连接它们。控制器对用户交互做出响应,更新模型中的数据并向视图提供所需要的数据。

如果此时没有弄清楚,并不要紧。在本书结尾处你将完全适应MVC模式,并熟悉如何将其应用到AngularJS。从第3章开始我深入到MVC模式的细节,当我在第6章中开始搭建一个更实际的AngularJS Web应用时,你将开始清晰地看到各个组件之间的区分。
控制器是由调用angular.module所返回的Module对象上的controller方法创建的,如前一节所示。传给controller方法的参数是新控制器的名称和一个将会被调用的函数,用于定义控制器功能,如清单2-4所示。

清单2-4 在todo.html文件中创建一个控制器
screenshot
惯例一般是对控制器命名为Ctrl,这里的帮助你识别出该控制器在你的应用程序中负责做什么。真正的应用程序一般会生成多个控制器,但是本例中仅需要一个,名字取为ToDoCtrl。
我承认这个控制器并未能给人留下深刻印象,但这是因为我创建的是一个尽量简单的控制器。控制器的主要目的之一是为了向视图提供其所需要的数据。你不会总是希望视图具有访问整个模型的权限,所以需要使用控制器明确地选出那部分可用的数据,被称作scope。

传给我的控制器函数的参数叫作$scope——也就是说,在$符号后紧跟着scope一词。在一个AngularJS应用中,以$开头的变量名表示AngularJS提供的内置特性。当你看到这个$符号时,一般是指一个内置服务,是一种自包含的组件,能够对多个控制器提供特性,但是$scope是比较特殊的,常用于向视图暴露数据和功能。我将在第13章中介绍scope,以及在第18~25章中介绍内置服务。

对于这个应用,我想让视图中可以使用整个model变量,所以我在$scope服务对象上定义了一个名为todo的属性,并将整个model变量赋给它,如下:
screenshot
这么做是为了能够在视图中使用模型数据而做的准备,马上将会对其进行演示。我还必须指定控制器所负责的HTML文档的区域,是通过使用ng-controller属性来完成的。因为我只有一个控制器(而且由于这是一个如此简单的应用),我就对body元素使用了ng-controller属性,如下:
screenshot

2.2.4 创建视图
通过将控制器所提供的数据和用于为浏览器生成显示内容的HTML元素绑定在一起,可以生成视图。在清单2-5中,你可以看到我是如何使用一种被称为数据绑定的注释来对HTML文档使用模型数据进行操作的。

清单2-5 在todo.html文件中通过视图显示模型数据
screenshot
你可以从浏览器中加载todo.html文件,从而看到将模型、控制器和视图绑定在一起所产生的效果,如图2-3所示。在后面各节中我将解释HTML是如何生成的。
screenshot
1.插入模型值
AngularJS使用两对大括号({{和}})表示一个数据绑定表达式。表达式的内容会被当作JavaScript计算,仅限于通过控制器赋给作用域上的数据和函数。在本例中,我只能访问模型中在定义控制器时赋给了$scope对象的那部分,通过使用在$scope对象上创建的属性名即可。

这就是说,例如,如果我想访问model.user属性,我得定义一个引用todo.user的数据绑定表达式,这是因为我将model对象赋给了$scope.todo属性。

AngularJS在文档中对HTML进行编译,发现ng-controller属性后,调用ToDoCtrl函数设置将被用于创建视图的作用域。当遇到每个数据绑定表达式后,AngularJS会查找$scope对象上的具体值,并向HTML文档中插入该值。举个例子,这个表达式:
screenshot
会被处理并转换成如下的字符串:
screenshot
这被称为数据绑定或者模型绑定,即模型中的值与某个HTML元素的内容相绑定。有几种不同的创建数据绑定的方法,将在第10章中加以解释。

2.计算表达式
数据绑定表达式的内容可以是任何有效的JavaScript语句,也就是说你可以执行从模型中创建新数据的操作。在清单2-5中,我使用这一特性在列表中显示待办事项的个数,如下:
screenshot
AngularJS计算这个表达式并显示数组中的元素个数,以告诉用户在待办事项列表中有多少个元素,在HTML文档的header旁边显示(使用了Bootstrap的label样式)。
3.使用指令
表达式还经常和指令一起使用,用于告诉AngularJS你希望内容如何被处理。在这份清单中用到了ng-repeat属性,这里使用了一个指令用于告诉AngularJS从一个集合中的各个对象生成所应用到的元素及其内容,如下:
screenshot
ng-repeat属性值的格式为 in 。我在todo.items中指定了item,就是说:为todo.items数组中的每个对象生成tr元素和所包含的td元素,并将数组中的对象逐个赋值给一个名为item的变量。

使用变量item,我就能够为数组中的每个对象的属性定义绑定表达式,产生如下的HTML。
screenshot


标签:

素材巴巴 Copyright © 2013-2021 http://www.sucaibaba.com/. Some Rights Reserved. 备案号:备案中。