第1页
AngularJS理论与实战
大漠穷秋
2014-07-12
第2页
核心议题
第3页
核心议题:共11个
AnguarJS的4大核心特性演示
自己动手搭建自动化的前端开发平台
核心特性1:MVC
核心特性2:模块化与依赖注入
核心特性3:双向数据绑定
路由:ngRoute与uiRouter
核心特性4:Directive与UI控件
Service、Provider、Factory
TDD与前端自动化测试
扩展主题:用AngularJS开发移动应用
第4页
AnguarJS的4大核心特性演示
第5页
AnguarJS的4大核心特性演示
第一个例子:MVC
第二个例子:模块化与依赖注入
第三个例子:双向数据绑定
第四个例子:指令与UI控件
第6页
MVC
View
Model
Controller
起源:1979年,Trygve Reenskaug第一次正式提出了MVC模式
Model:数据模型层
View:视图层,负责展示
Controller:业务逻辑和控制逻辑
好处:职责清晰,代码模块化
问题:为什么23中设计模式里面没有MVC?
第7页
模块化与依赖注入
第8页
单向数据绑定
目前大多数前端框架都是单向数据绑定:jQueryUI、BackBone、Flex
第9页
双向数据绑定
第10页
双向数据绑定
思考3个问题:
为什么其它所有前端框架都不实现双向数据绑定?
如果让你来实现双向数据绑定,你会怎么去实现?
双向数据绑定机制有什么潜在的缺点吗?
第11页
指令与UI控件
指令的本质:类似于taglib
第12页
指令与UI控件
http://angular-ui.github.io/
第13页
自己动手搭建自动化的前端开发平台
第14页
我们需要什么样的前端开发环境?
代码编辑工具---Sublime
断点调试工具---chrome+batarang
版本管理工具---git
代码合并和混淆工具---grunt
依赖管理工具---bower
单元测试工具---Karma+jasmine
集成测试工具---Protractor
第15页
基于NodeJS的工具集
Protractor
karma-coverage
第16页
开发和调试工具---NodeJS
http://nodejs.org/
第17页
代码合并和混淆工具---grunt
JS文件合并
JS代码自动压缩
每次Ctrl+S的时候自动执行以上动作
还可以每次Ctrl+S自动运行单元测试、集成测试
http://www.gruntjs.org/
Grunt把前端开发带入了自动化时代
第18页
依赖管理工具---bower
自动安装依赖的组件
组件之间的依赖检测
版本兼容性自动检测
http://bower.io/
前端组件自动化管理神器
第19页
轻量级Server---http-server
一款简单的http-sever
基于NodeJS的HTTP接口
https://github.com/nodeapps/http-server
模拟测试数据的神器
第20页
单元测试runner---karma
Pivotal Labs出品
原名:Testacular
2012年开源,2013年改名Karma
发音: ['kɑrmə] (中文模拟“卡马儿”)
含义:因果报应,因缘
Karma只是一款用来跑测试用例的runner
http://karma-runner.github.io/0.12/index.html
第21页
单元测试工具---jasmine
发音:['dʒæzmɪn]
含义:茉莉花
作用:类似Java里面的JUnit,提供了一套语法,用来编写测试用例
http://jasmine.github.io/
Jasmine四个核心概念:分组、用例、期望、匹配,分别对应Jasmine的四种函数:
describe(string,function)这个函数表示分组,也就是一组测试用例。
it(string,function)这个函数表示测试用例。
expect(expression)表示期望expression这个表达式具有某个值或者具有某种行为。
to***(arg)这个函数表示匹配。
第22页
专门为AngularJS定制的测试工具---Protractor
Protractor是一款集成测试工具,专门为AngularJS应用而设计;
Proctactor基于WebDriverJS;
原理:利用WebDriverJS,可以借助于NodeJS直接调用浏览器(IE、FF、Chrome)的接口;
https://github.com/angular/protractor
https://code.google.com/p/selenium/wiki/WebDriverJs
请注意,Protractor是为AngularJS专门定制的工具,但是WebDriverJS是通用的
第23页
一个完整的项目结构和演示
第24页
核心特性1:MVC
第25页
为什么需要MVC?
代码规模越来越大,切分职责是大势所趋
为了复用:很多逻辑是一模一样的
为了后期维护方便:修改一块功能不影响其它功能
第26页
数据模型
视图1
视图2
控制器
问题:如果“视图1”和“视图2”根本没有任何逻辑关系,“控制器”的角色就会很尴尬。
Controller的实现方式1
第27页
数据模型
视图1
视图2
控制器1
问题:如果“控制器1”和“控制器2”里面有2个方法是一模一样的,怎么办?
控制器2
Controller的实现方式2
第28页
数据模型
视图1
视图2
控制器1
请注意,这是个坑!在ng中请不要这样做!
控制器2
通用控制器
继承
继承
Controller的实现方式3
第29页
数据模型
视图1
视图2
控制器1
控制器2
Service
AngularJS中的Controller实现
第30页
不要试图去复用Controller,一个控制器一般只负责一小块视图
不要在Controller中操作DOM,这不是控制器的职责
不要在Controller里面做数据格式化,ng有很好用的表单控件
不要在Controller里面做数据过滤操作,ng有$filter服务
一般来说,Controller是不会互相调用的,控制器之间的交互会通过事件进行
AngularJS中使用Controller的注意点
第31页
$scope是一个POJO(Plain Old JavaScript Object)
$scope提供了一些工具方法$watch()/$apply()
$scope是表达式的执行环境(或者叫作用域)
$scope是一个树型结构,与DOM标签平行
子$scope对象会继承父$scope上的属性和方法
每一个Angular应用只有一个根$scope对象(一般位于ng-app上)
$scope可以传播事件,类似DOM事件,可以向上也可以向下
$scope不仅是MVC的基础,也是后面实现双向数据绑定的基础
可以用angular.element($0).scope()进行调试
AngularJS中MVC的核心是$scope
第32页
Creation
Watcher registration
Model mutation
Mutation observation
Scope destruction
$scope的生命周期
第33页
Sencha中的MVC实现
第34页
Backbone中的MVC实现
http://backbonejs.org/
第35页
核心特性2:模块化与依赖注入
第36页
一切都是从模块开始的
第37页
ng官方推荐的模块切分方式
app
controllers
directives
services
routes
filters
任何一个ng应用都是由控制器、指令、服务、路由、过滤器等有限的模块类型构成的
控制器、指令、服务、路由、过滤器分别放在一个模块里面(可借助于grunt合并)
用一个总的app模块作为入口点,它依赖其它所有模块
第38页
AngularJS的模块化实现
第39页
模块之间的依赖应该怎么做?---依赖注入
第40页
一个完整项目结构是什么样的?
npm配置项
各种基于NodeJS的工具
应用的主html文件
作为启动点的js
第41页
模块之间的依赖应该怎么做?---依赖注入
第42页
Angular的依赖注入实现
每一个Angular应用都有一个injector
injector负责自动处理依赖关系、实例化对象
对用户代码来说,injector是透明的
injector会自动分析函数签名,注入所需要的对象
声明依赖关系的三种方式:http://docs.angularjs.org/guide/di
DI可以用在各种不同的地方,主要用在controller和factory中
第43页
依赖注入的核心原理
分析匹配参数名
fn.$injections=[]
使用fn.call或者apply传递需要注入的对象
http://www.html-js.com/article/1980
第44页
核心特性3:双向数据绑定
第45页
最简单的例子
第46页
{{}}与ng-bind指令
在脚本没有加载完成时,用户会看到{{}},界面比较丑陋
一般做法:在index.html里面使用ng-bind,其它动态加载进来的内容使用{{}}
第47页
双向绑定的典型场景---表单
第48页
利用双向数据绑定实现动画:ngAnimate
http://css.doyoe.com/
第49页
思考问题
为什么大多数框架不实现双向绑定?双向绑定难在哪里?
如何进行“脏值检测”?
如何解决“振荡问题”或者“循环依赖问题”?
双向绑定有没有潜在的问题?
第50页
AngularJs双向绑定的大概步骤
用$watch()监控数据模型
$digest()启动脏值检测
触发视图变化
编译指令,设置监听器
定时器轮询、对象“深比较”
用事件通知指令刷新视图
第51页
AngularJs双向绑定的详细解释
在编译时,Angular使用$watch()在对应的$scope上添加了监控,一旦$scope中的属性值发生变化,这里就会跟着变。(脏值检测的$digest过程)
在指令编译时,Angular对input添加了事件监控,会自动把input的值设置到$scope中的对应属性上。
第52页
AngularJs双向绑定的核心代码
第53页
关于双向数据绑定的一些忠告
监控的表达式不要过于复杂,表达式数量不要太多
监听函数内不要有DOM操作,那样会显著降低性能
不能互相监听对方会修改的属性,以免形成交叉引用
ng默认的TTL是10次
深拷贝式的脏值检测会消耗更多内存(树形的JSON数据尤其如此)
http://www.csdn.net/article/2013-09-18/2816972-AngularJS-performance-tuning-for-long-list
大量数据列表的性能优化建议(核心都是尽量减少digest的次数):
第54页
路由:ngRoute与uiRouter
第55页
前端路由的概念
Ajax请求不会留下History记录
用户无法直接通过URL进入应用中的指定页面
Ajax对SEO是个灾难
路由的核心是给应用定义“状态”
使用路由机制会影响到应用的整体编码方式(需要预先定义好状态)
考虑兼容性问题与“优雅降级”
第56页
使用ngRoute进行视图之间的路由
第57页
第三方实现的ng-router实例
第58页
综合实例
多层嵌套的ui-view和命名ui-view
第59页
核心特性4:Directive与UI控件
第60页
最简单的指令
第61页
复杂一些的指令
第62页
指令嵌套
注意:使用Angular来封装UI控件可以让代码得到大幅度简化。
第63页
第三方UI库(指令库):angular-ui
http://angular-ui.github.io/
第64页
angular-ui:其它常用组件
http://angular-ui.github.io/
第65页
Directive机制的起源
http://www.w3.org/TR/NOTE-HTMLComponents
第66页
HTML Parser&Directives
指令的目的是用来自定义HTML标签,指令是一种标记,用来告诉HTML Parser“这里需要编译”
第67页
HTML Parser&Directives
Parser的本质:JS版的编译器
http://jsperf.com/
第68页
HTML Parser&Directives
compile
link
遍历DOM,找到所有指令
指令优先级排序;
执行compile函数;
把每个compile函数返回的
link函数打包到一个
总的link函数中
将scope绑定到DOM上;
在元素上注册事件监听器;
使用$watch监控数据模型;
...
常见的一些JS Template框架也采用了类似的compile策略以提升效率,比如HandleBars、ExtJS的XTemplate。从这个角度来看,可以把Angular的指令看作增强版的JS Template机制。
第69页
HTML Parser&Directives
var $compile = ...; // injected into your code
var scope = ...;
var html = '
';
// Step 1: parse HTML into DOM element
var template = angular.element(html);
// Step 2: compile the template
var linkFn = $compile(template);
// Step 3: link the compiled template with the scope.
linkFn(scope);
第70页
HTML Parser&Directives
指令嵌套
指令处理HTML元素
指令之间的交互
http://docs.angularjs.org/guide/directive
这是使用Angular封装UI组件的基础
第71页
Service、Provider、Factory
第72页
Service的概念
Service都是单例的
Service由$injector负责实例化
Service在整个应用的生命周期中存在,可以用来共享数据
在需要使用的地方利用依赖注入机制注入Service
自定义的Service需要写在内置的Service后面
内置Service的命名以$符号开头,自定义Service应该避免
第73页
AngularJS中常用的Service
第74页
创建自己的Service
第75页
Service、Provider、Factory
http://www.zhex.me/blog/2013/08/03/provider-factory-and-service-in-angularjs/
Service、Provider、Factory本质上都是Provider
Provider模式是“策略模式”+“抽象工厂模式”的混合体
第76页
其它常用的Service:内置的共24个
$compile:编译服务
$filter:数据格式化工具,内置了8个
$interval
$timeout
$locale
$location
$log
$parse
$http:封装了Ajax
http://www.ngnice.com/docs/api/ng/
第77页
TDD与前端自动化测试
第78页
JTestDriver
JsTestDriver运行界面
第79页
Karma
Pivotal Labs出品
原名:Testacular
2012年开源,2013年改名Karma
发音: ['kɑrmə] (中文模拟“卡马儿”)
含义:因果报应,因缘
Karma只是一款用来跑测试用例的runner
http://karma-runner.github.io/0.12/index.html
第80页
Jasmine
http://damoqiongqiu.iteye.com/blog/1925974
发音:['dʒæzmɪn]
含义:茉莉花
作用:类似Java里面的JUnit,提供了一套语法,用来编写测试用例
http://jasmine.github.io/
Jasmine四个核心概念:分组、用例、期望、匹配,分别对应Jasmine的四种函数:
describe(string,function)这个函数表示分组,也就是一组测试用例。
it(string,function)这个函数表示测试用例。
expect(expression)表示期望expression这个表达式具有某个值或者具有某种行为。
to***(arg)这个函数表示匹配。
第81页
扩展主题:用AngularJS开发移动应
第82页
WEBAPP核心思路
.ipa
.apk
.xap
打包
第83页
常用打包工具:Phonegap
http://phonegap.com/
第84页
常用打包工具:Appcan
http://www.appcan.cn/index.html
第85页
常用打包工具:appcelerator
http://www.appcelerator.com/
第86页
Phonegap暴露的设备API
第87页
常见WEB APP框架对比
优点:技术栈统一,学习成本低
缺点:低端安卓机存在性能问题
优点:各项技术架构都非常完善
缺点:学习成本高(与Extjs内核相同)
优点:衍生自jQuery,性能更好
缺点:有不少坑官方没有及时填起来
http://zeptojs.com/
http://jquerymobile.com/
第88页
常见WEB APP框架对比
第89页
Hybrid APP
http://div.io/topic/560
第90页
基于AngularJS的ionic
http://ionicframework.com/
第91页
核心议题:共11个
AnguarJS的4大核心特性演示
自己动手搭建自动化的前端开发平台
核心特性1:MVC
核心特性2:模块化与依赖注入
核心特性3:双向数据绑定
路由:ngRoute与uiRouter
核心特性4:Directive与UI控件
Service、Provider、Factory
TDD与前端自动化测试
扩展主题:用AngularJS开发移动应用
第92页
感谢聆听
QQ:253445528
更多文章:http://damoqiongqiu.iteye.com/