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 相关文章推荐
Moment.js 不容错过的超棒Javascript日期处理类库
Apr 15 Javascript
js鼠标点击事件在各个浏览器中的写法及Event对象属性介绍
Jan 24 Javascript
当鼠标滑过文本框自动选中输入框内容的JS代码分享
Nov 26 Javascript
控制input输入框中提示信息的显示和隐藏的方法
Feb 12 Javascript
DOM节点删除函数removeChild()用法实例
Jan 12 Javascript
JavaScript中的this,call,apply使用及区别详解
Jan 29 Javascript
如何判断Javascript对象是否存在的简单实例
May 18 Javascript
微信小程序radio组件使用详解
Jan 31 Javascript
mpvue中配置vuex并持久化到本地Storage图文教程解析
Mar 15 Javascript
vue多级复杂列表展开/折叠及全选/分组全选实现
Nov 05 Javascript
Angular2实现的秒表及改良版示例
May 10 Javascript
vue-router结合vuex实现用户权限控制功能
Nov 14 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下安装配置fckeditor编辑器的方法
2011/03/02 PHP
那些年一起学习的PHP(二)
2012/03/21 PHP
Zend studio文件注释模板设置方法
2013/09/29 PHP
php将HTML表格每行每列转为数组实现采集表格数据的方法
2015/04/03 PHP
twig模板常用语句实例小结
2016/02/04 PHP
php+ajax注册实时验证功能
2016/07/20 PHP
浅谈PHP发送HTTP请求的几种方式
2017/07/25 PHP
PDO::errorInfo讲解
2019/01/28 PHP
JScript中使用ADODB.Stream判断文件编码的代码
2008/06/09 Javascript
ext 代码生成器
2009/08/07 Javascript
Domino中运用jQuery读取视图内容的方法
2009/10/21 Javascript
jQuery EasyUI API 中文文档 - Tree树使用介绍
2011/11/19 Javascript
jquery prop的使用介绍及与attr的区别
2013/12/19 Javascript
jsp网页搜索结果中实现选中一行使其高亮
2014/02/17 Javascript
通过jquery实现页面的动画效果(实例代码)
2016/09/18 Javascript
VUE多层路由嵌套实现代码
2017/05/15 Javascript
AngularJS模态框模板ngDialog的使用详解
2018/05/11 Javascript
JavaScript实现数字前补“0”的五种方法示例
2019/01/03 Javascript
微信小程序 组件的外部样式externalClasses使用详解
2019/09/06 Javascript
jQuery实现可以扩展的日历
2020/12/01 jQuery
[47:48]DOTA2上海特级锦标赛D组小组赛#2 Liquid VS VP第三局
2016/02/28 DOTA
Python脚本实现下载合并SAE日志
2015/02/10 Python
编写Python脚本把sqlAlchemy对象转换成dict的教程
2015/05/29 Python
OpenCV-Python实现轮廓检测实例分析
2018/01/05 Python
pycharm新建一个python工程步骤
2019/07/16 Python
Python函数装饰器原理与用法详解
2019/08/16 Python
pyecharts绘制中国2020肺炎疫情地图的实例代码
2020/02/12 Python
python通过函数名调用函数的几种场景
2020/09/23 Python
linux面试题参考答案(9)
2015/01/07 面试题
村官工作鉴定评语
2014/01/27 职场文书
合作协议书范本
2014/04/17 职场文书
个人安全生产承诺书
2014/05/22 职场文书
教室标语大全
2014/06/21 职场文书
2014年机关工会工作总结
2014/12/19 职场文书
2015年教师见习期工作总结
2015/05/20 职场文书
SQL CASE 表达式的具体使用
2022/03/21 SQL Server