AngularJS -- AngularJS应用骨架 liujj@golden-tech liujj@golden-tech.

Slides:



Advertisements
Similar presentations
网络应用程序设计 2014 JavaBean. JavaBean 及其属性 JavaBean 就是一种 Java 的组件技术 JavaBean 是 Java 类 JavaBean 通过约定的方法名实现属性功能 简单属性 void setXxx(Type value) Type getXxx() boolean.
Advertisements

7.1 内置对象概述及分类 JSP 视频教学课程. JSP2.2 目录 1. 内置对象简介 1. 内置对象简介 2. 内置对象分类 2. 内置对象分类 3. 内置对象按功能区分 3. 内置对象按功能区分 4. 内置对象作用范围 4. 内置对象作用范围.
阻塞操作. 在 linux 里,一个等待队列由一个 wait_queue_head_t 类型的结构来描述 等待队列的初始化: static wait_queue_head_t testqueue; init_waitqueue_head(&testqueue);
第六 章数据库访问页 6.1 数据访问页视图 6.2 创建数据访问页 6.3 编辑数据访问页 6.4 查看数据访问页 退出.
6 Copyright © Oracle Corporation, All rights reserved. 维护控制文件.
Tool Command Language --11级ACM班 金天行.
Web图片搜索引擎设计 ——基于文本的图片信息提取.
AngularJS 常虎.
Oracle数据库 Oracle 子程序.
C++中的声音处理 在传统Turbo C环境中,如果想用C语言控制电脑发声,可以用Sound函数。在VC6.6环境中如果想控制电脑发声则采用Beep函数。原型为: Beep(频率,持续时间) , 单位毫秒 暂停程序执行使用Sleep函数 Sleep(持续时间), 单位毫秒 引用这两个函数时,必须包含头文件
全国计算机等级考试 二级基础知识 第二章 程序设计基础.
在PHP和MYSQL中实现完美的中文显示
移动开发的灵便迭代之道 黄凯.
武汉纺织大学传媒学院 cm.wtu.edu.cn
AngularJS -- 使用AngularJS进行开发
6.4 Notification 通知栏.
JavaScript 靜宜大學 資管系 楊子青.
大学计算机基础 典型案例之一 构建FPT服务器.
SQL Injection.
走进编程 程序的顺序结构(二).
辅导课程六.
Windows网络操作系统管理 ——Windows Server 2008 R2.
以ISI平台为例,为您演示一下如何在Endnote文献中查看该文献的References
数据挖掘工具性能比较.
PaPaPa项目架构 By:Listen 我在这.
用event class 从input的root文件中,由DmpDataBuffer::ReadObject读取数据的问题
任务1-3 使用Dreamweaver创建ASP网页
宁波市高校慕课联盟课程 与 进行交互 Linux 系统管理.
宁波市高校慕课联盟课程 与 进行交互 Linux 系统管理.
SOA – Experiment 2: Query Classification Web Service
C++语言程序设计 C++语言程序设计 第七章 类与对象 第十一组 C++语言程序设计.
第二章 登录UNIX操作系统.
UC九游 天猪(atian25) AngularJS 进阶实践 UC九游 天猪(atian25)
简单介绍 用C++实现简单的模板数据结构 ArrayList(数组, 类似std::vector)
$9 泛型基础.
Web安全基础教程
顺序表的删除.
第四章 团队音乐会序幕: 团队协作平台的快速创建
Drupal Dev 我想知道:什么时候、什么变化.
VisComposer 2019/4/17.
VB与Access数据库的连接.
分裂对象模型 C++ otcl.
项目二:HTML语言基础.
Web安全基础教程
本节内容 Win32 API中的宽字符 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
成绩是怎么算出来的? 16级第一学期半期考试成绩 班级 姓名 语文 数学 英语 政治 历史 地理 物理 化学 生物 总分 1 张三1 115
第4章 Excel电子表格制作软件 4.4 函数(一).
第九节 赋值运算符和赋值表达式.
iSIGHT 基本培训 使用 Excel的栅栏问题
Chapter 18 使用GRASP的对象设计示例.
多层循环 Private Sub Command1_Click() Dim i As Integer, j As Integer
魏新宇 MATLAB/Simulink 与控制系统仿真 魏新宇
Touch Github = Touch the World
Delphi 7.0开发示例.
第7章 模板 陈哲 副教授 南京航空航天大学 计算机科学与技术学院.
GIS基本功能 数据存储 与管理 数据采集 数据处理 与编辑 空间查询 空间查询 GIS能做什么? 与分析 叠加分析 缓冲区分析 网络分析
本节内容 C语言的汇编表示 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
Python 环境搭建 基于Anaconda和VSCode.
基于列存储的RDF数据管理 朱敏
本节内容 动态链接库 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
Web前端开发 第17章:AngularJS 阮晓龙 /
WEB程序设计技术 数据库操作.
本节内容 进程 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
使用ADO访问数据库 李宝智 BonizLee 课程 10564A
创建、启动和关闭Activity 本讲大纲: 1、创建Activity 2、配置Activity 3、启动和关闭Activity
编程达人-- 从零开始学UI系列教程 第九节、布尔运算 先行者 YC.
使用Fragment 本讲大纲: 1、创建Fragment 2、在Activity中添加Fragment
RefWorks使用指南 归档、管理个人参考文献.
§2 自由代数 定义19.7:设X是集合,G是一个T-代数,为X到G的函数,若对每个T-代数A和X到A的函数,都存在唯一的G到A的同态映射,使得=,则称G(更严格的说是(G,))是生成集X上的自由T-代数。X中的元素称为生成元。 A变, 变 变, 也变 对给定的 和A,是唯一的.
学习目标 1、什么是列类型 2、列类型之数值类型.
Presentation transcript:

AngularJS -- AngularJS应用骨架 liujj@golden-tech liujj@golden-tech

调用Angular 为了使用Angular,所有应用都必须首先做两件事情: 加载angular.js库 使用ng-app指令告诉Angular应该管理DOM的哪一部分 liujj@golden-tech

加载脚本 从Google的内容分发网络(CDN)中加载类库 在国内的话最好使用本地的路径 <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script> 在国内的话最好使用本地的路径 liujj@golden-tech

使用ng-app声明Angular的边界 可以用ng-app指令告诉Angular应该管理页面中的哪一块(html标签、某个div标签等) liujj@golden-tech

Model View Controller Model View Controller mvc.01.text.html 使用对象的属性来创建数据模型,甚至只用基本数据类型来存储数据。 var messages = { someText : ‘You have started your journey.’ }; View HTML页面(DOM) <p>{{someText}}</p> <!-- 双花括号插值语法 --> Controller 编写的类或者类型 function TextController($scope) { $scope.messages = messages; } 上面这种写法是在全局作用域中创建了TextController。虽然对于示例代码来说,这没有上面问题,但是其实定义控制器的正确方式是,把它定义成模块的一部分,控制器可以为应用里相关的部分提供命名空间机制。 liujj@golden-tech mvc.01.text.html mvc.02.model.html

在模块中定义控制器 mvc.03.myApp.html <html ng-app=‘myApp’> <!-- 1.把ng-app属性设置成模块的名称myApp --> <body ng-controller='TextController'> <p>{{messages.someText}}</p> <script type="text/javascript" src="angular.js"></script> <script type="text/javascript"> // 2.调用angular对象创建一个名为myApp的模块 var myAppModule = angular.module('myApp', []); // 3.把控制器函数传递给myApp模块的controller函数 myAppModule.controller('TextController', function ($scope) { var messages = { someText : 'Your have started your journey.' }; $scope.messages = messages; } ); </script> </body> </html> liujj@golden-tech mvc.03.myApp.html

模板和数据绑定 基本的运作流程: 用户请求应用起始页。 用户的浏览器向服务器发起一次HTTP连接,然后加载index.html页面,这个页面里包含了模板。 Angular被加载到页面中,等待页面加载完成,然后查找ng-app指令,用来定义模板边界。 Angular遍历模板,查找指令和绑定关系,这将触发一系列动作:注册监听器、执行一些DOM操作、从服务器获取初始化数据。这项工作的最后结果是,应用将会启动起来,并且模板被转换成DOM视图。 连接都服务器去加载需要给用户的其他数据。 对于每一个Angular应用来说,步骤1到3都是标准化的,步骤4和5是可选的。 为了提升性能,对于应用中的第一个视图,可以把数据和HTML模板一起加载进来,从而避免发起多次请求。 使用Angular构建应用的时候,可以将应用中的模板和数据分离开来。这样就可以把模板缓存起来。在第一次请求之后,只需要把新的数据下载到浏览器中即可。 liujj@golden-tech

显示文本 使用ng-bind指令,可以在UI中的任何地方显示并刷新文本。它有两种等价形式: 使用双花括号的形式 <p>{{greeting.text}}</p> 使用基于属性的指令 <p ng-bind='greeting.text'></p> 创建双花括号语法的目的是为了阅读起来更加自然,并且需要输入的内容更少。 虽然两种形式的输出内容相同,但是使用双花括号语法的时候,在Angular使用数据替换这些花括号之前,第一个加载页面,也就是应用中的index.html,其未被渲染好的模板可能会被用户看到。 造成这种现象的原因是,浏览器需要首先加载HTML页面,渲染它,然后Angular才有机会把它解释成你期望看到的内容 好消息是,在大多数模板中你依然可以使用{{ }}。但是,对于index.html页面中的数据绑定操作,建议使用ng-bind。这样一来,在数据加载完之前你的用户就不会看到任何内容。 liujj@golden-tech ng-bind.html

表单输入 可以使用ng-model属性把元素绑定到模型属性上 这一机制对所有标准的表单元素都可以起作用(如文本框,单选框,复选框等) <input type="checkbox" ng-model="youCheckedIt"> <p>{{youCheckedIt}}</p> liujj@golden-tech

ng-change ng-change属性指定一个控制器方法,一旦修改了输入值,这个方法就会被调用 <form ng-controller='StartUpController'> Starting: <input ng-change='computeNeeded()' ng-model='funding.startingEstimate'> Recommendation: {{funding.needed}} </form> <script type="text/javascript" src="angular.js"></script> <script type="text/javascript"> function StartUpController ($scope) { $scope.funding = {startingEstimate: 0}; $scope.computeNeeded = function() { $scope.funding.needed = $scope.funding.startingEstimate * 10; }; } </script> liujj@golden-tech form.input.02.compute.needed.html

$watch()函数 使用ng-change会有一个潜在的问题,即,只有当用户在文本框中输入的时候才去计算所需的金额。 function StartUpController ($scope) { $scope.funding = {startingEstimate: 0}; computeNeeded = function() { $scope.funding.needed = $scope.funding.startingEstimate * 10; }; $scope.$watch('funding.startingEstimate', computeNeeded); } liujj@golden-tech form.input.04.compute.needed.watch.html

列表、表格以及其它迭代性元素 ng-repeat将会生成标签内部所有HTML元素的一份拷贝,包括放指令的标签。 $index返回当前引用的元素序号 $first、$middle、$last返回布尔值,表示当前元素是否是集合中的第一个元素、中间的某个元素,或者最后一个元素 <div ng-controller='AlbumController'> <table> <tr ng-repeat='track in album'> <td>{{$index + 1}}</td> <td>{{track.name}}</td> <td>{{track.duration}}</td> </tr> </table> </div> liujj@golden-tech ng-repeat.03.album.index.html

隐藏和显示 ng-show、ng-hide 这两个命令是等价的,但是运行效果正好相反 ng-show为true时将显示元素,为false时将会隐藏元素;ng-hide正好相反。 <div ng-controller='DeathrayMenuController'> <button ng-click="toggleMenu()">Toggle Menu</button> <ul ng-show='menuState'> <li ng-click="stun()">Stun</li> <li ng-click="disintegrate()">Disintegrate</li> <li ng-click="erase()">Erase from history</li> </ul> </div> function DeathrayMenuController($scope) { $scope.menuState = false; $scope.toggleMenu = function() { $scope.menuState = !$scope.menuState; }; } ng-show.html

CSS类和样式 ng-class、ng-style <div ng-controller='HeaderController'> 这两个都可以接受一个表达式: 表示CSS类名的字符串,以空格分隔 CSS类名数组 CSS类名到布尔值的映射 <div ng-controller='HeaderController'> <div ng-class='{error: isError, warning: isWarning}'>{{messageText}}</div> <button ng-click="showError()">Simulate Error</button> <button ng-click="showWarning()">Simulate Warning</button> </div> function HeaderController($scope) { $scope.isError = false; $scope.isWarning = false; ...... } liujj@golden-tech ng-class.01.error.warning.html

src和href属性 src/ng-src href/ng-href 推荐使用ng-src和ng-href。 <img src = "./images/{{favoriteCat}}"> <img ng-src = "./images/{{favoriteCat}}"> href/ng-href <a href = "./shop/category={{numberOfBalloons}}">numberOfBalloons</a> <a ng-href = "./shop/category={{numberOfBalloons}}">numberOfBalloons</a> 推荐使用ng-src和ng-href。 liujj@golden-tech

表达式 在模板中使用表达式是为了以充分的灵活性在模板、业务逻辑和数据之间建立联系,同时又能避免让业务逻辑渗透到模板中。 表达式 数学运算(+、-、/、*、%) 比较运算(==、!=、>、<、>=、<=) 布尔运算(&&、||、!) 位运算(\^、&、|) 还可以调用控制器中$scope对象上所暴露的函数,引用数组和对象符合([]、{}、.) liujj@golden-tech

<div ng-controller=‘SomeController'> <div>{{recompute() / 10}}</div> <ul ng-repeat=‘thing in things’> <li ng-class=‘{highlight: $index % 4 >= threshold($index)}’> {{otherFunction($index)}} </li> </ul> </div> 【 recompute() / 10 】虽然是合法的,但是它也是把业务逻辑放到模板中的一个典型例子,应该避免这种做法。 liujj@golden-tech

区分UI和控制器的职责 在应用中控制器有三种职责 为了让控制器保持小巧和可管理状态,建议为视图中的每一块功能区域创建一个控制器。 为应用中的模型设置初始状态 通过$scope对象把数据模型和函数暴露给视图(UI模板) 监视模型其余部分的变化,并采取相应的动作 为了让控制器保持小巧和可管理状态,建议为视图中的每一块功能区域创建一个控制器。 有两种方法可以把控制器关联到DOM节点 在模板中通过ng-controller属性来声明 通过路由把它绑定到一个动态加载的DOM模板片段上,这个模板叫做视图 如果UI中带有一个非常复杂的区域,可以创建嵌套的控制器,它们可以通过继承树结构来共享数据模型和函数,这样就可以保持代码的简单和可维护性。 <div ng-controller=“ParentController”> <div ng-controller=“ChildController”>...</div> </div> 虽然把这种方式叫做控制器嵌套,但真实的嵌套发生在$scope对象上。通过内部的原型继承机制,父控制器对象上的$scope会被传递给内部嵌套控制器的$scope。

利用$scope暴露模型数据 利用向控制器传递$scope对象的机制,可以把模型数据暴露给视图。 在你的应用中可能还有其他数据,但是只有通过$scope触及这些数据,Angular才把它当成数据模型的一部分。 对于显示的创建$scope属性(例如:$scope.count = 5),还可以通过模板自身创建数据模型。 通过表达式。 <button ng-click=‘count=5’>Set count to three</button> 在表单输入项上使用ng-model(建立双向绑定关系)。 liujj@golden-tech

使用$watch 监控数据模型的变化 当数据模型中某一部分发生变化时,$watch函数可以发出通知。 函数签名: $watch(watchFn, watchAction, deepWatch) watchFn:一个带有Angular表达式或者函数的字符串 watchAction:一个函数或者表达式,当watchFn发生变化时会被调用。 如果是函数,其函数签名为 function(newValue, oldValue, scope) deepWatch:如果设置为true,将会命令Angular去检查被监控对象的每个属性是否发生了变化。 $watch函数会返回一个函数,当不在需要接收变更通知时,可以用这个返回的函数注销监控。 var dereg = $scope.$watch(‘someModel.someProperty’,callbackOnChange()); dereg(); liujj@golden-tech

// $scope.totalCart总共被执行了几次? <div ng-repeat='item in items'> <span>{{item.title}}</span> <input ng-model='item.quantity'> <span>{{item.price | currency}}</span> <span>{{item.price * item.quantity | currency}}</span> </div> <div>Total:{{totalCart() | currency}}</div> <div>Discount:{{bill.discount | currency}}</div> <div>Subtotal:{{subtotal() | currency}}</div> function CartController ($scope) { $scope.bill = {}; $scope.items = [ {title: 'Paint pots', quantity: 8, price: 3.95}, {title: 'Polka dots', quantity: 17, price: 12.95}, {title: 'Pebbles', quantity: 5, price: 6.95} ]; $scope.totalCart = function() { var total = 0; for (var i = 0, len = $scope.items.length; i < len; i++) { total = total + $scope.items[i].price * $scope.items[i].quantity; } return total; }; $scope.subtotal = function() { return $scope.totalCart() - $scope.bill.discount; function calculateDiscount (newValue, oldValue, scope){ $scope.bill.discount = newValue > 100 ? 10 : 0; $scope.$watch($scope.totalCart, calculateDiscount); // $scope.totalCart总共被执行了几次? wacth.01.html

$watch中的性能注意事项 上面的例子存在潜在的性能问题 为什么是6次呢? 该函数被调用了6次 虽然在这个例子中性能问题并不明显,但在更复杂的应用中,运行6次就会成为一个问题 为什么是6次呢? liujj@golden-tech

一回目 二回目 三回目 wacth.01.html <div ng-repeat='item in items'> <span>{{item.title}}</span> <input ng-model='item.quantity'> <span>{{item.price | currency}}</span> <span>{{item.price * item.quantity | currency}}</span> </div> <div>Total:{{totalCart() | currency}}</div> <div>Discount:{{bill.discount | currency}}</div> <div>Subtotal:{{subtotal() | currency}}</div> function CartController ($scope) { $scope.bill = {}; $scope.items = [ {title: 'Paint pots', quantity: 8, price: 3.95}, {title: 'Polka dots', quantity: 17, price: 12.95}, {title: 'Pebbles', quantity: 5, price: 6.95} ]; $scope.totalCart = function() { var total = 0; for (var i = 0, len = $scope.items.length; i < len; i++) { total = total + $scope.items[i].price * $scope.items[i].quantity; } return total; }; $scope.subtotal = function() { return $scope.totalCart() - $scope.bill.discount; function calculateDiscount (newValue, oldValue, scope){ $scope.bill.discount = newValue > 100 ? 10 : 0; $scope.$watch($scope.totalCart, calculateDiscount); 一回目 二回目 三回目 wacth.01.html

$watch中的性能注意事项 为什么是6次呢? Angular这样做的目的 Angluar的做法 如何解决这个问题? 其中有3次很容易跟踪到 {{totalCart() | currency}} {{subtotal() | currency}} $scope.$watch($scope.totalCart, calculateDiscount); 然后Angular把以上整个过程又重复了一遍,最终就是6次了。 Angular这样做的目的 检测模型中的变更已经被完整的进行了传播,并且模型已经被设置好。 Angluar的做法 把所有被监控的属性都拷贝一份,然后把他们和当前的值进行比较,看看是否发生了变化。实际上,Angular可能会把以上程序运行10次,从而确保进行了完整的传播。如果经过10次重复之后被监控的属性还在发生变化,Angular将会报错并退出。 如何解决这个问题? liujj@golden-tech

$watch 1.监控items数组的变化 监控items数组的变化,然后重新计算$scope属性中的总价、折扣和小计值。 缺点 <div>Total:{{bill.totalCart | currency}}</div> <div>Discount:{{bill.discount | currency}}</div> <div>Subtotal:{{bill.subtotal | currency}}</div> var calculateTotals = function() { var total = 0; for (var i = 0, len = $scope.items.length; i < len; i++) { total = total + $scope.items[i].price * $scope.items[i].quantity; } $scope.bill.totalCart = total; $scope.bill.discount = total > 100 ? 10 : 0; $scope.bill.subtotal = total - $scope.bill.discount; }; $scope.$watch('items', calculateTotals, true); 缺点 既然在监控items数组,Angular就会制作一份数组的拷贝,用来进行比较操作。 对于大型的items数组来说,如果每次在Angular显示页面时只需要重新计算bill属性,那么性能会好很多。 liujj@golden-tech wacth.02.html

$watch 2.只重新计算bill属性 这种写法为什么只计算bill属性? wacth.03.html <div>Total:{{bill.totalCart | currency}}</div> <div>Discount:{{bill.discount | currency}}</div> <div>Subtotal:{{bill.subtotal | currency}}</div> function CartController ($scope) { $scope.bill = {}; $scope.items = [ {title: 'Paint pots', quantity: 8, price: 3.95}, {title: 'Polka dots', quantity: 17, price: 12.95}, {title: 'Pebbles', quantity: 5, price: 6.95} ]; $scope.$watch(function() { var total = 0; for (var i = 0, len = $scope.items.length; i < len; i++) { total = total + $scope.items[i].price * $scope.items[i].quantity; } $scope.bill.totalCart = total; $scope.bill.discount = total > 100 ? 10 : 0; $scope.bill.subtotal = total - $scope.bill.discount; }); } 这种写法为什么只计算bill属性? liujj@golden-tech wacth.03.html

$watch 监控多个东西 监控把这些属性连接起来之后的值 把他们放到一个数组或者对象中,然后给deepWatch参数传递给一个true值 $scope.$watch(‘things.a + things.b’, callMe(...)); a、b可以属于不同的对象,只要需要,这个列表可以无限长。 如果非常长,你就需要写一个函数来返回连接之后的值,而不是依赖一个表达式来完成这一逻辑。 把他们放到一个数组或者对象中,然后给deepWatch参数传递给一个true值 $scope.$watch(‘things’, callMe(...), true); Angular遍历things属性,然后当其中任何一个属性发生变化时就调用callMe(). liujj@golden-tech

使用Module(模块) 组织依赖关系 业务代码放在哪里? 前面的例子中都是放在控制器的函数中。 这种做法对于小型的应用和例子来说可以工作的很好;但在真实项目中,这种做法很快就会使代码变的无法维护。控制器将会变成一个垃圾场,我们要做的所有东西都会倒在这里。 模块提供了一种方法,可以用来组织应用中一块功能区域的依赖关系;同时还提供了一种机制,可以自动解析依赖关系(又叫做依赖注入)。 liujj@golden-tech

【例】获取商品列表 -- 没有模块 代码复用性差 功能边界划分困难 单元测试困难 function ItemsViewController($scope) { // 向服务器发起请求 ...... // 解析响应并放入Items对象 var items = [ {Title: 'Paint pots', Description: 'Pots full of paint', Price: 3.95}, {Title: 'Polka dots', Description: 'Dots with polka', Price: 2.95}, {Title: 'Pebbles', Description: 'Just little rocks', Price: 6.95} ]; // 把Items数组设置到$scope上,这样视图才能够现实它 $scope.items = items; }); 代码复用性差 功能边界划分困难 单元测试困难 liujj@golden-tech

【例】获取商品列表 -- 利用模块 控制器代码变得很简单。 var shoppingModule = angular.module('ShoppingModule', []); // 组织依赖关系 shoppingModule.factory('ItemsService', function() { var itemsService = {}; itemsService.query = function () { return [ {Title: 'Paint pots', Description: 'Pots full of paint', Price: 3.95}, {Title: 'Polka dots', Description: 'Dots with polka', Price: 2.95}, {Title: 'Pebbles', Description: 'Just little rocks', Price: 6.95} ]; }; return itemsService; }); // 自动解析依赖关系(依赖注入) function CartController ($scope, ItemsService) { $scope.items = ItemsService.query(); } 控制器代码变得很简单。 liujj@golden-tech

创建服务 provider(name, Objcet or constructor()) 一个可配置的服务,创建的逻辑比较复杂。 如果传递一个Objcet作为参数,那么这个Object必须带有一个名为$get的函数,这个函数需要返回服务的名字;否则,Angular会认为传递的是一个构造函数,调用构造函数会返回服务实例对象。 factory(name, $getFunction()) 一个不可配置的服务,创建逻辑比较复杂。 需要指定一个函数,当调用这个函数的时候,会返回服务的实例。 可以把它看成provider(name, {$get: $getFunction()}) service(name, constructor()) 一个不可配置的服务,创建逻辑比较简单。 与上面provider函数的constructor参数类似,Angular调用它可以创建服务实例。 liujj@golden-tech

模块依赖 使用Module接口来定义模块之间的依赖关系。 如果打算使用第三方包中所提供的服务或者指令,它们一般会带有自己的模块。由于你的应用会依赖这些模块,所以需要在应用模块中定义依赖关系才能引用它们。 例:引用(假象)模块SnazzyUIWidgets和SuperDataSync var appMod = angular.module(‘app’, [‘SnazzyUIWidgets’, ‘SuperDataSync’]); liujj@golden-tech

使用过滤器格式化数据 可以用过滤器来声明应该如何变换数据格式,然后再显示给用户 过滤器的语法 {{ expression | filterName : parameter1 : ...parameterN }} 例: {{ 12.9 | currency }} ⇒ $12.90 Angular内置的其他过滤器还有date、number、uppercase等 在绑定过程中,可以用管道符号把过滤器连接起来 例: {{ 12.9 | number:0 | currency }} ⇒ $13.00 liujj@golden-tech

自定义过滤器 // 首字母大写过滤器 <p>{{pageHeading | titleCase}}</p> var homeModule = angular.module('HomeModule', []); homeModule.filter('titleCase', function(){ var titleCaseFilter = function(input) { var words = input.split(' '); for (var i = 0; i < words.length; i++) { words[i] = words[i].charAt(0).toUpperCase() + words[i].slice(1); }; return words.join(' '); return titleCaseFilter; }); function HomeController ($scope) { $scope.pageHeading = 'behold the majesty of your page title'; } liujj@golden-tech

使用路由和$location 切换视图 虽然从技术上来说AJAX应用确实是单页面应用,但是很多时候,出于各种原因,我们需要为用户展示或者隐藏一些子页面视图。我们可以利用Angular的$route服务来管理这种场景。 利用路由服务来定义这样一种东西:对于浏览器所指向的URL,Angular将会加载并显示一个模板,并实例化一个控制器来为模板提供内容。 可以通过调用$routeProvider服务上的函数来创建路由,把需要创建的路由当成一个配置块传给这些参数即可。 liujj@golden-tech

var aMailServices = angular var aMailServices = angular.module('AMail', []); function emailRouteConfig ($routeProvider) { $routeProvider.when('/', { controller: ListController, templateUrl: 'list.html' }).when('/view/:id', { controller: DetailController, templateUrl: 'detail.html' }).otherwise({ redirectTo: '/' }); } aMailServices.config(emailRouteConfig); messages = [ ... ]; function ListController ($scope) { $scope.messages = messages; } function DetailController ($scope, $routeParams) { $scope.message = messages[$routeParams.id]; } 在URL、模板和控制器之间建立映射关系 '/':ListController:'list.html' 在id前面加了一个冒号,从而制定了一个参数化的URL组件 配置路由,以便Amail服务能够找到它 通过$routeParams.id取得传递的参数

与服务器交互 真正的应用需要和真实的服务器进行交互 Angular提供了一个叫做$http的服务。 提供了一个可扩展的方法列表,使得与服务器的交互更加容易 支持HTTP,JSON和CORS方式 包含了安全性支持,避免JSON格式的脆弱性和XSRF(跨站请求伪造) [ { "title": 'Paint pots', "quantity": 8, "price": 3.95. }, "title": 'Polka dots', "quantity": 17, "price": 12.95. "title": 'Pebbles', "quantity": 5, "price": 6.95. } ] function ShoppingController ($scope, $http) { $http.get('/products').success(function(data, status, headers, config) { $scope.items = data; }); } liujj@golden-tech

function ShoppingController ($scope, $http) { $http.get('/products').success(function(data, status, headers, config) { $scope.items = data; }); } JSON返回值例: [ { "title": 'Paint pots', "quantity": 8, "price": 3.95. }, "title": 'Polka dots', "quantity": 17, "price": 12.95. "title": 'Pebbles', "quantity": 5, "price": 6.95. } ] liujj@golden-tech

使用指令修改DOM 指令扩展了HTML语法,同时它也是使用自定义的元素和属性把行为和DOM转换关联到一起的方式 当内置指令无法满足需求时,可以自定义指令 与服务一样,可以通过模块对象的API来定义指令,只要调用模块实例的directive()函数即可,其中directiveFunction是一个工厂函数,用来定义指令的特性 var appModule = angular.module(‘appModule’, [...]); appModule.directive(‘directiveName’, directiveFunction); liujj@golden-tech

【例】autofocus <button ngbk-focus>I'm very focused!</button> var appModule = angular.module('app', []); appModule.directive('ngbkFocus', function(){ return { link: function (scope, element, attrs, controller) { element[0].focus(); } }; }); liujj@golden-tech

校验用户输入 Angular允许为表单中的输入元素定义一个合法的状态,并且只有当所有元素都是合法状态时才允许提交表单。 required type='email' type='number' 可以通过$valid属性获取表单的校验状态 <form name='addUserForm'> <div>First name: <input ng-model='user.first' required></div> <div>Last name: <input ng-model='user.last' required></div> <div>Email: <input type='email' ng-model='user.email' required></div> <div>Age: <input type='number' ng-model='user.age' ng-maxlength='3' ng-minlength='1'></div> <div><button>Submit</button></div> </form> liujj@golden-tech