AngularJS入门教程之AngularJS 模板


Posted in Javascript onAugust 18, 2016

是时候给这些网页来点动态特性了——用AngularJS!我们这里为后面要加入的控制器添加了一个测试。

一个应用的代码架构有很多种。对于AngularJS应用,我们鼓励使用模型-视图-控制器(MVC)模式解耦代码和分离关注点。考虑到这一点,我们用AngularJS来为我们的应用添加一些模型、视图和控制器。

请重置工作目录:

git checkout -f step-2

我们的应用现在有了一个包含三部手机的列表。

步骤1和步骤2之间最重要的不同在下面列出。,你可以到GitHub去看完整的差别。

视图和模板

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

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

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

 <ul>
  <li ng-repeat="phone in phones">
   {{phone.name}}
  <p>{{phone.snippet}}</p>
  </li>
 </ul>
</body>
</html>

我们刚刚把静态编码的手机列表替换掉了,因为这里我们使用ngRepeat指令和两个用花括号包裹起来的AngularJS表达式——{{phone.name}}和{{phone.snippet}}——能达到同样的效果。

在<li>标签里面的ng-repeat="phone in phones"语句是一个AngularJS迭代器。这个迭代器告诉AngularJS用第一个<li>标签作为模板为列表中的每一部手机创建一个<li>元素。

正如我们在第0步时学到的,包裹在phone.name和phone.snippet周围的花括号标识着数据绑定。和常量计算不同的是,这里的表达式实际上是我们应用的一个数据模型引用,这些我们在PhoneListCtrl控制器里面都设置好了。

AngularJS入门教程之AngularJS 模板

模型和控制器

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

app/js/controller.js:

function PhoneListCtrl($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的作用域,请参看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来运行单元测试。你可以像下面这样运行测试:

在一个单独的终端上,进入到angular-phonecat目录并且运行./scripts/test-server.sh来启动测试(Windows命令行下请输入.\scripts\test-server.bat来运行脚本,后面脚本命令运行方式类似);

打开一个新的浏览器窗口,并且转到http://localhost:9876 ;

选择“Capture this browser in strict mode”。

这个时候,你可以抛开你的窗口不管然后把这事忘了。JsTestDriver会自己把测试跑完并且把结果输出在你的终端里。

运行./scripts/test.sh进行测试 。

你应当看到类似于如下的结果:

Chrome: Runner reset.
.
Total 1 tests (Passed: 1; Fails: 0; Errors: 0) (2.00 ms)
 Chrome 19.0.1084.36 Mac OS: Run 1 tests (Passed: 1; Fails: 0; Errors 0) (2.00 ms)

耶!测试通过了!或者没有... 注意:如果在你运行测试之后发生了错误,关闭浏览器然后回到终端关了脚本,然后在重新来一边上面的步骤。

练习

为index.html添加另一个数据绑定。例如:

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

创建一个新的数据模型属性,并且把它绑定到模板上。例如:

$scope.hello = "Hello, World!"

更新你的浏览器,确保显示出来“Hello, 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>
</table>

确定把toBe(3)改成toBe(4)之后单元测试失败,然后重新跑一遍./scripts/test.sh脚本

总结

你现在拥有一个模型,视图,控制器分离的动态应用了,并且你随时进行了测试。现在,你可以进入到步骤3来为应用加入全文检索功能了。

以上就是对AngularJS 模板的资料整理,后续继续补充相关资料,谢谢大家对本站的支持!

Javascript 相关文章推荐
五段实用的js高级技巧
Dec 20 Javascript
js设置文本框中焦点位置在最后的示例代码(简单实用)
Mar 04 Javascript
基于Bootstrap+jQuery.validate实现Form表单验证
Dec 16 Javascript
JavaScript常用脚本汇总(一)
Mar 04 Javascript
JS实现自动变化的导航菜单效果代码
Sep 09 Javascript
javascript实现tab切换特效
Nov 12 Javascript
详解JavaScript表单验证(E-mail 验证)
Mar 31 Javascript
JS中使用变量保存arguments对象的方法
Jun 03 Javascript
详解Angular2学习笔记之Html属性绑定
Jan 03 Javascript
element-ui 表格实现单元格可编辑的示例
Feb 26 Javascript
JS中实现隐藏部分姓名或者电话号码的代码
Jul 17 Javascript
Taro UI框架开发小程序实现左滑喜欢右滑不喜欢效果的示例代码
May 18 Javascript
AngularJS入门教程之静态模板详解
Aug 18 #Javascript
AngularJS入门教程引导程序
Aug 18 #Javascript
Bootstrap模态框(modal)垂直居中的实例代码
Aug 18 #Javascript
js 获取站点应用名的简单实例
Aug 18 #Javascript
BootStrap日期控件在模态框中选择时间下拉菜单无效的原因及解决办法(火狐下不能点击)
Aug 18 #Javascript
js修改onclick动作的四种方法(推荐)
Aug 18 #Javascript
AngularJS 整理一些优化的小技巧
Aug 18 #Javascript
You might like
php中定时计划任务的实现原理
2013/01/08 PHP
PHP实现设计模式中的抽象工厂模式详解
2014/10/11 PHP
利用PHP如何写APP接口详解
2016/08/23 PHP
javascript 避免闭包引发的问题
2009/03/17 Javascript
jquery实现点击TreeView文本父节点展开/折叠子节点
2013/01/10 Javascript
js验证IP及子网掩码的合法性有效性示例
2014/04/30 Javascript
JavaScript正则表达式之multiline属性的应用
2015/06/16 Javascript
JavaScript中innerHTML,innerText,outerHTML的用法及区别
2015/09/01 Javascript
jQuery改变form表单的action,并进行提交的实现代码
2016/05/25 Javascript
AngularJS教程之MVC体系结构详解
2016/08/16 Javascript
jQuery Validate 无法验证 chosen-select元素的解决方法
2017/05/17 jQuery
老生常谈ES6中的类
2017/07/31 Javascript
js原生方法被覆盖,从新赋值原生的方法
2018/01/02 Javascript
通过jquery toggleClass()属性制作文章段落更改背景颜色
2018/05/21 jQuery
Electron-vue脚手架改造vue项目的方法
2018/10/22 Javascript
vue-cli脚手架引入弹出层layer插件的几种方法
2019/06/24 Javascript
vue引入微信sdk 实现分享朋友圈获取地理位置功能
2019/07/04 Javascript
解决Vue-Router升级导致的Uncaught (in promise)问题
2020/08/07 Javascript
微信小程序实现弹幕墙(祝福墙)
2020/11/18 Javascript
Python中用PIL库批量给图片加上序号的教程
2015/05/06 Python
如何通过python的fabric包完成代码上传部署
2019/07/29 Python
python实现录屏功能(亲测好用)
2020/03/02 Python
利用Python脚本批量生成SQL语句
2020/03/04 Python
基于python实现FTP文件上传与下载操作(ftp&amp;sftp协议)
2020/04/01 Python
Python3.9.0 a1安装pygame出错解决全过程(小结)
2021/02/02 Python
使用css3做0.5px的细线的示例代码
2018/01/18 HTML / CSS
野兽派官方旗舰店:THE BEAST 野兽派
2016/08/05 全球购物
德国专业木制品经销商:Holz-Direkt24
2019/12/26 全球购物
在C语言中"指针和数组等价"到底是什么意思?
2014/03/24 面试题
我想声明一个指针并为它分配一些空间, 但却不行。这些代码有什么 问题?char *p; *p = malloc(10);
2016/10/06 面试题
护理自我鉴定范文
2013/10/06 职场文书
和平主题的演讲稿
2014/01/12 职场文书
大学生旅游业创业计划书
2014/01/29 职场文书
高中运动会入场词
2014/02/14 职场文书
学校出纳员岗位职责
2014/03/18 职场文书
MySQL学习总结-基础架构概述
2021/04/05 MySQL