2-Angular 模板

AngularJS与MVC设计模式构建动态应用

现在是时候让我们的页面动起来了——使用AngularJS,我们同时测试我们给controller添加的代码的可行性。 有很多方法去组织代码编写程序,对于Angular程序,你们鼓励使用 模型-视图-控制器 (MVC设计模式)(本站也有 介绍)去解耦代码,分离关注点。针对这个想法,让我们用一点点Angular和JavaScrip给我们的应用增加模型、视图、控制器组件。

  • 现在三个手机的数据自动生成。

工作空间重置介绍 重置你的工作区间到第二步

git checkout -f step-2

刷新你的浏览器,或者在线上检出这一步:第二步例子 大部分重要的修改都列在下面,你在 GitHub上能看全部不同:

视图与模板

在Angular中,通过HTML模板,视图是模型的投影。这意味着无论模型修改什么,Angular都刷新合适的绑定点来会刷新视图。 视图是由Angular使用下面的模板构建:

<html ng-app="phonecatApp">
<head>
  ...
  <script src="bower_components/angular/angular.js"></script>
  <script src="js/controllers.js"></script>
</head>
<body ng-controller="PhoneListCtrl">

  <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>元素。

  • 表达式用双花括号包裹,{{phone.name}}{{phone.snippet}}将会用值替换掉表达式。

我们增加了命令,叫 ng-controller, 依附 <body>标签的 PhoneListGtrl 控制器,在这些点:

  • 在双花括号中的表达式{{phone.name}}{{phone.snippet}}表示数据绑定,他引用到我们在PhoneListCtrl控制器里应用模型中。

注意:我们已经使用ng-app="phonecatApp" 定义一个Angular模块读取,phonecatApp是模块的名称,模块会包括PhoneListsCtrl

模型与控制器

现在数据模型在PhoneListCtrl控制器中被实例化,控制器有一个简单的构造器接受$scope参数。 app/js/controllers.js:

var phonecatApp = angular.module('phonecatApp', []);

phonecatApp.controller('PhoneListCtrl', function ($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.'}
  ];
});

  这里我们定义了一个叫 PhoneListCtrl的控制器,注册到AngularJS模块phoncatApp中。注意当启动angular应用,现在我们 ng-app命令(在 <html>上)指定了phoneApp模块名字当作模块去读取。 虽然控制器现在工作不是很好,但他扮演了关键角色,他提供了上下文环境给我们的模型,控制器允许我们在模型与视图中建立数据绑定,我们连接不同的点在介绍,数据和逻辑之间,如下:

  • ngController命令在body标签上,指向我们的控制器的名字,PhoneListCtrl(在javascrip文件上)

  • PhoneListCtrl控制器连接手机数据到$scope,$scope会注入到我们的控制器中,这个范围是根范围的原型后代,当程序被创建的时候就被定义,控制器范围对所有在<body ng-controller="PhoneListCtrl">标签内的绑定可见。

范围

范围的概念十分关键,一个范围可以看作是胶水,允许模版、模型与控制器一同工作,Angular使用范围,让在模版、模型、控制器中的数据相互隔离,但是又同步。对模型做出的修改都会反应到视图中,发生在视图中的修改也会反应到模型中。 学习更多的关于Angular范围,看 angular范围文档

测试

当你们开发中,用Angular方法从视图操作控制器,让测试变得容易,如果我们的控制器对全局命名空间可见,那么我们就能简单地用mock范围对象实例化他。

describe('PhoneListCtrl', function(){

  it('should create "phones" model with 3 phones', function() {
    var scope = {},
        ctrl = new PhoneListCtrl(scope);

    expect(scope.phones.length).toBe(3);
  });

});

测试实例化 PhoneListCtrl,并验证了范围中手机含有三条记录,这个例子证明了在Angular中创建单元测试是多么简单,当测试成为如此决定性的部分,我们让测试在Angular容易创建,所以鼓励开发者写测试。

测试非全局控制器

在实际中,你可能不想你的控制器工作在全局变量中,相反,你可以看到我们通过匿名构造器注册一个到 phonecatApp模块上。 在这个案子中,Angular提供了一个服务 $controller 他会通过名字检索控制器,这里用 $controller是相同的测试。

  • 在每个测试之前,我们告诉Angular去读取phonecatApp模块。

  • 我们要求Angular注册$controller服务到我们的测试方法中。

  • 我们使用$controller去创建PhoneListCtrl实例。

  • 使用这位实例,我们验证范围内手机列表中三条记录。

写并跑测试

在写测试的时候,Angular开发者比较喜欢Jasmine的行为驱动开发框架的语法。虽然Angular不要求你使用Jasmin,我们用Jasmine v1.3写了教程中的所有测试,你可以在 Jasmine的首页Jasmine的文档中学习更多关于Jasmine。 angular种子项目已经预配置使用Karma运行所有的测试,但是你必须确保 Karma和他所需插件已经装上,你可以运行 npm install安装。 运行测试,并观察文件修改: npm test

  • Karmma将会自动启动一个Chrome的新实例,可以忽略他让他在后台运行,Karma会使用他执行所有的测试。

  • 在终端你可能会看见下面或相似的输出:

info: Karma server started at http://localhost:9876/
  info (launcher): Starting  browser "Chrome"
  info (Chrome 22.0): Connected on socket id tPUm9DXcLHtZTKbAEO-n
  Chrome 22.0: Executed 1 of 1 SUCCESS (0.093 secs / 0.004 secs)

好,测试通过或者没有……

  • 重新运行测试,只要修改任何源码或test.js,Karma会注意这个修改并重新给你运行测试,怎么样,很贴心吧。

确保你没有最小化Karma打开的浏览器,在某些OS中,分配给最小化浏览器的内存是有限的,这就当你的karma测试运行十分缓慢。

实验

添加另一个绑定给 index.html。如:

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

在控制器中创建一个新的模型属性,在模板中绑定,如:

$scope.name = "World";

然后增加一个绑定到index.html

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

刷新你的浏览器,验证他是否说“Hello,Wolrd!” 从 ./test/unit/shontrollerSpec.js 的控制器中更新单元测试,去反射当前的修改,如增加:

expect(scope.name).toBe('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的表格。 修改 toBe(4)代替 expect(scope.phones.length).toBe(3),让单元测试失败。

总结

现在你有一个动态应用,特地分开了模型、视图与控制器组件,你测试了你所做,现在去 第三步学习如何给你的应用添加一个全文检索。 原文地址: https://docs.angularjs.org/tutorial/step_02

转载于:https://my.oschina.net/markho/blog/498150

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值