是时候用AngularJS生成我们的动态页面了。

通常我们有很多方法来构建一个应用的代码。对于Angular的应用,我们鼓励使用MVC设计模式来解耦代码并且实现职责独立。记住这个,现在让我们在我们的应用中使用一点Angular和Javascript来添加模型,视图和控制器成分。

  ·列表中的三部电话是由数据动态生成的。

最重要的不同将会在下面阐述,您可以点击这里在GitHub上查看所有的不同。

视图和模板

在Angular中,视图是数据模型通过html模板的映射。这意味着无论何时模型改变了,Angular将会刷新适当的数据绑定域,也就是更新视图。

在这个模板中,视图是被Angular生成的:

app/index.html:

<html ng-app="phonecatApp">
<head>
...
<script src="bower_components/angular/angular.js"></script>
<script src="app.js"></script>
</head>
<body ng-controller="PhoneListController"> <ul>
<li ng-repeat="phone in phones">
<span>{{phone.name}}</span>
<p>{{phone.snippet}}</p>
</li>
</ul> </body>
</html>

  

我们通过ngRepeat指令和两条Angular表达式替换了硬编码的电话列表:

  ·在<li>标签中的ng-repeat="phone in phones"属性是Angular的迭代器。这个迭代器告诉Angular,使用<li>标签作为模板为列表中的每一部电话创建一个<li>标签。

  ·被双花括号绑定的({{phone.name}} 和 {{phone.snippet}})将会被表达式的值替代。

我们添加了一条新的指令,叫做ngController,它在<body>标签上绑定了一个PhoneListController控制器。这时:

  ·在花括号中的表达式 ({{phone.name}} 和{{phone.snippet}}) 意味着绑定,这涉及到我们的数据模型,而这又是在我们的PhoneListController控制器中建立的。

注意:我们通过使用ng-app="phonecatApp"指定了一个Angular模块,这里phonecatApp是我们的模块名。这个模块包含PhoneListController控制器。

模型和控制器

数据模型(一个在文本中创建的简单的电话数组)现在被PhoneListController控制器实例化了。控制器仅仅是一个使用了$scope的构造函数:

app/app.js:

// Define the `phonecatApp` module
var phonecatApp = angular.module('phonecatApp', []); // Define the `PhoneListController` controller on the `phonecatApp` module
phonecatApp.controller('PhoneListController', function PhoneListController($scope) {
$scope.phones = [
{
name: 'Nexus S',
snippet: 'Fast just got faster with Nexus S.'
}, {
name: 'Motorola XOOM™ with Wi-Fi',
snippet: 'The Next, Next Generation tablet.'
}, {
name: 'MOTOROLA XOOM™',
snippet: 'The Next, Next Generation tablet.'
}
];
});

  

这里我们声明了一个叫做PhoneListController的控制器并将其在AngularJS模块(phonecatApp)中注册,注意到在引导Angular应用的过程中,我们的ng-app(在<html>标签中)指令指定了phonecatApp模块作为加载模块。

虽然至今控制器并没有做很多事,但它扮演了一个非常重要的角色。通过提供我们数据模型的环境,控制器允许我们在模型和视图中建立数据绑定。我们在展示层,数据层和逻辑层建立了如下的联系:

  ·位于<body>标签中的ngController指令,引用了我们控制器的PhoneListController(位于javascript文件夹下的app.js).

  ·PhoneListController将电话数据传入了被注入到我们控制器函数的$scope,scope是root scope的一个典型后代(一旦应用被定义)。这个控制器scope是所有位于<body ng-controller="PhoneListController">标签中的绑定可以获取的。

作用域

在Angular中,作用域的概念是极其重要的。scope可以看做是粘合模板,数据模型和控制器一起工作的胶水。Anglular使用scopes,包含在模板,数据模型和控制器中的信息来保持数据模型和视图的独立但同步,任何数据模型的改变会反应到视图上;任何视图的改变也会反映的数据模型上。

(进一步学习scope,请参考这里。)

Angular中的作用域原型继承与其父作用域,沿着这种关系直到根作用域。直接在作用域中赋值使得在页面的不同部分分享数据和创建相互影响的应用变得非常容易。当这种做法被应用到原型和规模更小的应用时,这会很快在数据模型中导致紧耦合,同时也很难溯源修改。

在接下来的步骤中,我们将会学习到如何更好地组织我们的代码,通过将相关的应用和展示逻辑“打包”成独立的,可复用的实体,我们称之为“组件”(component)。

测试

用“Angular方式”来将控制器从视图中独立出来,可以容易地测试代码像它被生成那样。如果我们的控制器在全局命名空间中是可获取的,那我们可以通过一个模仿的作用域对象来实例化它:

describe('PhoneListController', function() {

  it('should create a `phones` model with 3 phones', function() {
var scope = {};
var ctrl = new PhoneListController(scope); expect(scope.phones.length).toBe(3);
}); });

实验

在index.html中添加另一个绑定,比如:

<p>Total number of phones: {{phones.length}}</p>

在控制器创建一条新的模型属性并将其绑定到模板上,比如:

$scope.name = "World";

并在index.html上添加绑定:

<p>Hello, {{name}}!</p>

刷新你的浏览器来证实确实输出了“Hello,World”。

在index.html中使用迭代器来创建一张简单的表:

<table>
<tr><th>row number</th></tr>
<tr ng-repeat="i in [0, 1, 2, 3, 4, 5, 6, 7]"><td>{{i}}</td></tr>
</table>

现在,使将列表变为基于1的递增绑定:

<table>
<tr><th>row number</th></tr>
<tr ng-repeat="i in [0, 1, 2, 3, 4, 5, 6, 7]"><td>{{i+1}}</td></tr>
</table>

额外作业:尝试使用额外的ng-repeat来创建一张8x8的表。

总结

现在您已经创建了一个将视图,模型和控制器独立的动态应用,让我们接下来学习如何通过组件来改善我们应用的架构吧。

[Angular Tutorial] 2-Angular Templates的更多相关文章

  1. [Angular Tutorial] 0-Bootstraping

    在这一节的tutorial中,您将会逐渐熟悉AngularJS phonecat app的最重要的源代码文件.您也将学到如何将开发服务器与angular-seed绑定到一起,并且在浏览器中运行应用. ...

  2. [Angular Tutorial]PhoneCat Tutorial App

    (注:曾经在<不敢止步>一书中看到学到一个观点,作者认为学习一门技术最好的方法就是翻译某部领域书籍.这里我决定做一次尝试,接下来花1个月左右时间,将Angular Tutorial Pho ...

  3. [Angular Tutorial] 6-Two-way Data Binding

    在这一步中,您将会添加一个新特性来使得您的用户可以控制电话列表中电话的顺序,动态改变顺序是由创建一个新的数据模型的特性实现的,将它和迭代器绑定在一起,并且让数据绑定神奇地处理下面的工作. ·除了搜索框 ...

  4. Angular 1与 Angular 2之间的一些差别

    现在在用ng1.5.8做一个项目,ng的优点和特性我就不用多说了,ng1在陆续更新到1.5/1.6后就没再推出新版本了,ng2已经面世测试很久了,如同很多系统和框架一样,每个大的版本更新都会有新特性加 ...

  5. AngularJs angular.injector、angular.module

    angular.injector 创建一个injector对象, 调用injector对象的方法可用于获取服务以及依赖注入. 格式:angular.injector(modules); modules ...

  6. angular.js 的angular.copy 、 angular.extend 、 angular.merge

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  7. Angular - - angular.injector、angular.module

    angular.injector 创建一个injector对象, 调用injector对象的方法可用于获取服务以及依赖注入. 格式:angular.injector(modules); modules ...

  8. 使用Angular CLI生成 Angular 5项目

    如果您正在使用angular, 但是没有好好利用angular cli的话, 那么可以看看本文. Angular CLI 官网: https://github.com/angular/angular- ...

  9. Angular 2 to Angular 4 with Angular Material UI Components

    Download Source - 955.2 KB Content Part 1: Angular2 Setup in Visual Studio 2017, Basic CRUD applicat ...

  10. Angular 学习笔记 (Angular 9 & ivy)

    refer : https://blog.angularindepth.com/all-you-need-to-know-about-ivy-the-new-angular-engine-9cde47 ...

随机推荐

  1. linux下执行scrapy的爬虫定时任务

    刚开始执行scrapy crawl zentaos可以完成扫描 但是通过linux的crontab任务,只执行了连接mongodb的操作,并创建了索引 也就是说scrapy crawl zentaos ...

  2. Chapter 1 First Sight——19

    "I'm headed toward building four, I could show you the way…" Definitely over-helpful. &quo ...

  3. ArrayList遍历的同时删除--- 删除还是用迭代器的比较好,其它的都会有问题.

    http://javag.iteye.com/blog/403097 ArrayList遍历的同时删除-- 删除还是用迭代器的比较好,其它的都会有问题.     博客分类: 随笔 Javathread ...

  4. 把一个 int 数字 n 格式化成16进制的字符串(前面补零成0位)

    例如,输入n=10,要求输出 0x0000000A; C++:  sprintf( buffer, "0x%08X", n); C#:    string s = string.F ...

  5. 基于ATmgea8单片机设计的加热控制系统(转)

    源:http://blog.163.com/zhaojun_xf/blog/static/3005058020085102562729/ 1 引言 温度是工业生产中主要的被控参数之一,与之相关的各种温 ...

  6. ListView下拉刷新、上拉载入更多之封装改进

    在Android中ListView下拉刷新.上拉载入更多示例一文中,Maxwin兄给出的控件比较强大,前面有详细介绍,但是有个不足就是,里面使用了一些资源文件,包括图片,String,layout,这 ...

  7. Windows环境下使用VS2005编译OpenSSL

    如何Windows环境下,使用VS2005编译OpenSSL,虽然这个问题在Baidu.Google上一堆,但安装中还是遇到些问题,在这里 记录下来希望能帮助大家不要在走弯路.注:我是在WinXP S ...

  8. dwr.xml 配置

    dwr.xml 是你用来配置 DWR 的文件,默认是将其放入 WEB-INF 文件夹. 创建一个 dwr.xml 文件dwr.xml 有如下的结构: <?xml version="1. ...

  9. Android音频系统之AudioPolicyService

    地址:http://blog.csdn.net/edmond999/article/details/18599327 1.1 AudioPolicy Service 在AudioFlinger小节,我 ...

  10. DWR3.0框架入门(2) —— DWR的服务器推送

    DWR3.0框架入门(2) —— DWR的服务器推送 DWR 在开始本节内容之前,先来了解一下什么是服务器推送技术和DWR的推送方式.   1.服务器推送技术和DWR的推送方式   传统模式的 Web ...