是时候用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. 忘了SA密码的SQL SERVER

    [暂时还未验证] SQL2008  如果 本地连接登录补上,也忘了Sa等管理账号的密码,可以通过单用户连接的方式登录 http://msdn.microsoft.com/zh-cn/library/m ...

  2. BootStrap详解之(二)

    六.内容 Bootstrap 将全局 font-size 设置为 14px,line-height 设置为 1.428 中心内容 .lead 将字体大小.加粗.行高修改 (无卵高深用) 标记 mark ...

  3. LayoutParams 命名的时候,最好用与子控件相关的字符串命名,

    @Override public View initView() { RelativeLayout container = new RelativeLayout(UIUtils.getContext( ...

  4. 解开神秘面纱之“AngualrJS 中指令相关的嵌入作用域和模板作用域”

    原文:https://www.airpair.com/angularjs/posts/transclusion-template-scope-in-angular-directives#r1 原标题: ...

  5. C/C++ strtok函数

    一.头文件:#include <string.h> 二.函数原型:char * strtok (char *str, const char * delimiters); 三.参数:str, ...

  6. css中margin重叠和一些相关概念(包含块containing block、块级格式化上下文BFC、不可替换元素 non-replaced element、匿名盒Anonymous boxes )

    平时在工作中,总是有一些元素之间的边距与设定的边距好像不一致的情况,一直没明白为什么,最近仔细研究了一下,发现里面有学问:垂直元素之间的margin有有互相重叠的情况:新建一个BFC后,会阻止元素与外 ...

  7. android4.0 的图库Gallery2代码分析(二)

    最近迫于生存压力,不得不给人兼职打工.故在博文中加了个求点击的链接.麻烦有时间的博友们帮我点击一下.没时间的不用勉强啊.不过请放心,我是做技术的,肯定链接没病毒,就是我打工的淘宝店铺.嘻嘻.http: ...

  8. Cow Rectangles

    Cow Rectangles 题目描述 The locations of Farmer John's N cows (1 <= N <= 500) are described by dis ...

  9. Windows下编译mxnet

    操作系统: 64位Windows10 mxnet的构建和安装包括两个步骤: 第一步,编译出共享库 libmxnet.dll. 第二步,安装语言包,比如python等. 最小编译要求: 最新的支持C++ ...

  10. php命名空间如何引入一个变量类名?

    例子如下: $className = 'Test'; 正常 new \Require\allClass\Test(); 当然OK,但是 new \Require\allClass\$className ...