AngularJS 学习笔记之第一张AngularJS 模板

2015年02月25日 javascript 暂无评论 阅读 36 views 次

请重置工作目录:

git checkout -f step-2

 

在AngularJS中,一个视图是模型通过HTML**模板**渲染之后的映射。这意味着,不论模型什么时候发生变化,AngularJS会实时更新结合点,随之更新视图。

比如,视图组件被AngularJS用下面这个模板构建出来:

<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>

2015-02-25_113457

tutorial_02

模型和控制器

PhoneListCtrl控制器里面初始化了数据模型(这里只不过是一个包含了数组的函数,数组中存储的对象是手机数据列表):

 

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——控制器方法的名字(在JS文件controllers.js中)和<body>标签里面的ngController指令的值相匹配。
  • 手机的数据此时与注入到我们控制器函数的作用域$scope)相关联。当应用启动之后,会有一个根作用域被创建出来,而控制器的作用域是根作用域的一个典型后继。这个控制器的作用域对所有<body ng-controller="PhoneListCtrl">标记内部的数据绑定有效。

AngularJS的作用域理论非常重要:一个作用域可以视作模板、模型和控制器协同工作的粘接器。AngularJS使用作用域,同时还有模板中的信息,数据模型和控制器。这些可以帮助模型和视图分离,但是他们两者确实是同步的!任何对于模型的更改都会即时反映在视图上;任何在视图上的更改都会被立刻体现在模型中。

测试

“AngularJS方式”让开发时代码测试变得十分简单。让我们来瞅一眼下面这个为控制器新添加的单元测试:

test/unit/controllersSpec.js:

describe('PhoneCat controllers', function() {

  describe('PhoneListCtrl', function(){

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

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

这个测试验证了我们的手机数组里面有三条记录(暂时无需弄明白这个测试脚本)。这个例子显示出为AngularJS的代码创建一个单元测试是多么的容易。正因为测试在软件开发中是必不可少的环节,所以我们使得在AngularJS可以轻易地构建测试,来鼓励开发者多写它们。

在写测试的时候,AngularJS的开发者倾向于使用Jasmine行为驱动开发(BBD)框架中的语法。尽管AngularJS没有强迫你使用Jasmine,但是我们在教程里面所有的测试都使用Jasmine编写。你可以在Jasmine的官方主页或者Jasmine Wiki上获得相关知识。

基于AngularJS的项目被预先配置为使用JsTestDriver来运行单元测试。你可以像下面这样运行测试:

  1. C:Usersdellnodejsstudyangular-phonecatscriptsprivate>npm test
    > angular-phonecat@0.0.0 pretest C:Usersdellnodejsstudyangular-phonecat
    > npm installnpm WARN package.json karma-chrome-launcher@0.1.7 No README data> angular-phonecat@0.0.0 postinstall C:Usersdellnodejsstudyangular-phonecat
    > bower install
    > angular-phonecat@0.0.0 test C:Usersdellnodejsstudyangular-phonecat
    > node node_modules/karma/bin/karma start test/karma.conf.jsWARN [plugin]: Cannot find plugin "karma-firefox-launcher".
    Did you forget to install it ?
    npm install karma-firefox-launcher --save-dev
    INFO [karma]: Karma v0.12.31 server started at http://localhost:9876/
    INFO [launcher]: Starting browser Chrome
    WARN [watcher]: Pattern "C:/Users/dell/nodejsstudy/angular-phonecat/app/bower_components/angular-route/angular-route.js" does not ma
    INFO [Chrome 40.0.2214 (Windows 7)]: Connected on socket Q4jVwe-voQGFNtV413Uo with id 33812342
    Chrome 40.0.2214 (Windows 7): Executed 1 of 1 SUCCESS (0.015 secs / 0.013 secs)2015-02-25_114743
  2. 耶!测试通过了!或者没有... 注意:如果在你运行测试之后发生了错误,关闭浏览器然后回到终端关了脚本,然后在重新来一边上面的步骤。

练习

  • index.html添加另一个数据绑定。例如:
    <p>Total number of phones: {{phones.length}}</p>
  • Update the unit test for the controller in ./test/unit/controllersSpec.js to reflect the previous change. For example by adding:
    expect(scope.name).toBe('World');
  • 用一个迭代器创建一个简单的表:
    <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>

    现在让数据模型表达式的i增加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>

 

给我留言

您必须 登录 才能发表留言!

Copyright © 大一网 保留所有权利.  

用户登录

分享到: