Transcript 为什么其它所有前端框架都不实现双向数据绑定
AngularJS理论与实战
大漠穷秋 2014-10-25 1
我是大漠穷秋 本名:章小飞 公司:ZTEsoft 职位:技术架构师 技能:Java、ActionScript/Flex、jQuery/Extjs/AngularJS...
著作:《Ext江湖》 《ActionScript3.0游戏设计基础(第二版)》 《用AngularJS开发下一代WEB应用》 2
内容概要 AngularJS简介 自己动手搭建前端自动化开发平台 实例演示AngularJS核心特性 AngularJS核心原理简析 使用AngularJS开发移动APP TDD和前端自动化测试 3
AngularJS简介
4
AngularJS 简介 Misko Hevery Since 2009 MIT License 5
AngularJS 简介 目前最新版本1.3.0
放弃了IE8 引入了单向数据绑定 删掉了一堆过时的API(据说是为了AngularJS2.0做准备) 6
前端开发工具
7
思考:我们需要什么样的前端开发环境? 代码编辑工具 断点调试工具 版本管理工具 代码合并和混淆工具 依赖管理工具 单元测试工具 集成测试工具 刀耕火种的时代已经过去,前端开发急需自动化、工业化!!! 8
AngularJS开发环境 代码编辑工具-- Sublime 断点调试工具-- chrome+batarang 版本管理工具-- git 代码合并和混淆工具-- grunt 依赖管理工具-- bower 单元测试工具-- Karma+jasmine 集成测试工具-- Protractor 9
常见前端开发工具,请 按需搭配
karma-coverage Protractor
10
开发和调试工具-- NodeJS http://nodejs.org/ 11
代码合并和混淆工具-- Grunt JS文件合并 JS代码自动压缩 每次Ctrl+S的时候自动执行以上动作 还可以每次Ctrl+S自动运行单元测试、集成测试 http://www.gruntjs.org/
Grunt把前端开发带入了自动化时代
12
AngularJS核心特性
13
Angular核心特性 特性1:MVC 特性2:模块化与依赖注入 特性3:指令系统 特性4:双向数据绑定 ngRouter、uiRouter、AngularUI Provider、Service、Factory 14
特性1:MVC
15
MVC Model Controller View 起源:1979年, Trygve Reenskaug 第一次正式提出了MVC模式 Model:数据模型层 View:视图层,负责展示 Controller:业务逻辑和控制逻辑 好处:职责清晰,代码模块化 问题:为什么23中设计模式里面没有MVC? 16
AngularJS中使用Controller的注意点 不要试图去复用Controller,一个控制器一般只负责一小块视图 不要在Controller中操作DOM,这不是控制器的职责 不要在Controller里面做数据格式化,ng有很好用的表单控件 不要在Controller里面做数据过滤操作,ng有$filter服务 一般来说, Controller是不会互相调用的 ,控制器之间的交互会通过事件进行 17
AngularJS中MVC的核心是 $scope $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()进行调试 18
$scope的生命周期 Creation Watcher registration Model mutation Mutation observation Scope destruction 19
Sencha中的MVC实现 20
Backbone中的MVC实现 http://backbonejs.org/ 21
特性2:模块化与依赖注入
22
AngularJS核心特性2-- 模块化Module 23
ng官方推荐的模块切分方式 app controllers directives services routes filters 任何一个ng应用都是由控制器、指令、服务、路由、过滤器等有限的模块类型构成的 控制器、指令、服务、路由、过滤器分别放在一个模块里面(可借助于grunt合并) 用一个总的app模块作为入口点,它依赖其它所有模块 24
AngularJS的模块化实现 25
模块之间的依赖-- 依赖注入 26
特性3:指令系统
27
最简单的指令 28
复杂一些的指令 29
指令嵌套 注意:使用Angular来封装UI控件可以让代码得到大幅度简化。 30
AngularUI http://angular-ui.github.io/ 31
ng-grid http://angular-ui.github.io/ 32
后台管理型UI特性分析 33
互联网和电商型UI特性分析 34
后台管理型系统必备的UI组件 http://miniui.com/ 共36个,红框中为重量级组件 35
后台管理型系统必备的UI组件 http://sencha.com/ 36
互联网和电商型系统必备UI组件 http://gallery.kissyui.com/coms 37
特性4:双向数据绑定
38
AngularJS核心特性4-- 双向数据绑定 39
AngularJS核心特性4-- 双向数据绑定 40
AngularJS核心特性4-- 双向数据绑定 思考3个问题: 为什么其它所有前端框架都
不实现
双向数据绑定? 如果让你来实现双向数据绑定,你会怎么去实现? 双向数据绑定机制有什么潜在的问题吗? 41
最简单的例子 42
{{}}与ng-bind指令 在脚本没有加载完成时,用户会看到{{}},界面比较丑陋 一般做法:在index.html里面使用ng-bind,其它动态加载进来的内容使用{{}} 43
双向绑定的典型场景---表单 44
双向数据绑定实现动画:ngAnimate http://css.doyoe.com/ 45
思考问题 为什么大多数框架不实现双向绑定?双向绑定难在哪里? 如何进行“
脏值检测
”? 如何解决“
振荡问题
”或者“
循环依赖问题
”? 双向绑定有没有潜在的问题? 46
AngularJS双向绑定的大概步骤 用$watch()监控数据模型 编译指令,设置监听器 $digest()启动脏值检测 定时器
轮询
、对象“
深比较
” 触发视图变化 用事件通知
指令
刷新视图 47
关于双向数据绑定的一些忠告 监控的表达式不要过于复杂,表达式数量不要太多 监听函数内
不要有DOM操作
,那样会显著降低性能 不能互相监听对方会修改的属性,以免形成交叉引用 ng默认的TTL是 10 次 深拷贝式的脏值检测会消耗更多内存(树形的JSON数据尤其如此) 大量数据列表的性能优化建议( 核心都是尽量减少digest的次数 ): http://www.csdn.net/article/2013-09-18/2816972-AngularJS-performance-tuning-for-long-list 48
ngRouter、uiRouter、AngularUI
49
前端路由的概念 Ajax请求不会留下History记录 用户无法直接通过URL进入应用中的指定页面 Ajax对SEO是个灾难 路由的核心是给应用定义“状态” 使用路由机制会影响到应用的整体编码方式(需要预先定义好状态) 考虑兼容性问题与“优雅降级” 50
使用ngRoute进行视图之间的路由 51
第三方实现的ng-router实例 52
综合实例 多层嵌套的ui-view和命名ui-view 53
Provider、Service、Factory 54
Service的概念 Service都是 单例 的 Service由$injector负责实例化 Service在整个应用的生命周期中存在,可以用来 共享数据 在需要使用的地方利用 依赖注入 机制注入Service 自定义的Service需要写在内置的Service后面 内置Service的命名以$符号开头,自定义Service应该避免 55
AngularJS中常用的Service 56
创建自己的Service 57
Service、Provider、Factory Service、Provider、Factory本质上都是Provider Provider模式是“策略模式”+“抽象工厂模式”的混合体 http://www.zhex.me/blog/2013/08/03/provider-factory-and-service-in-angularjs/ 58
其它常用的Service:内置的共24个 $compile:编译服务 $filter:数据格式化工具,内置了8个 $interval $timeout $locale $location $log $parse $http:封装了Ajax http://www.ngnice.com/docs/api/ng/ 59
AngularJS核心原理简析
60
AngularJS核心原理简析 AngularJS的启动过程 Provider与Injector 指令的执行过程 $scope与双向数据绑定 61
AngularJS的启动过程 62
指令的执行过程:compile与link compile函数的作用是对指令的模板进行转换; link的作用是在模型和视图之间建立关联,包括在元素上注册事件监听; scope在链接阶段才会被绑定到元素上,因此compile阶段操作scope会报错; 对于同一个指令的多个实例,compile只会执行一次;而link对于指令的每个实例都会执行一 次; 一般情况下我们只要编写link函数就够了; 请注意,如果你编写的自定义的compile函数,自定义的link函数无效,因为compile函数应 该返回一个link函数供后续处理; 63
双向数据绑定:最简单的一维结构 } { email:'[email protected]', password:'20070702' 64
双向数据绑定:二维表格 ] [ {index:1,firstName:'Mark',lastName:'Otto',userName:'@mdo'}, {index:2,firstName:'Jacob',lastName:'Thomton',userName:'@fat'}, {index:3,firstName:'Larry',lastName:'the Bird',userName:'@twitter'} 65
双向数据绑定:Tree型结构 } { } root:{ name:'root', showRoot:false, children:[ { name:'Base', children:[ //... ] } //...
] 由于ng的$digest机制和“对象深比较”机制,ng在处理Tree型结构方面性能非常差; 后面分析$digest源码的过程中会解释; 建议不要对Tree型结构使用双向数据绑定! 66
ng支持哪些类型的表达式? 数学运算:+ 、- 、/ 、* 、% 比较运算:= = 、! = 、> 、< 、> = 、< = 布尔运算:& & 、| | 、!
位运算:^ 、 & 、| 对象和数组字面值:[ ] 、{ } 注意:不支持if/for/while等控制逻辑! 67
自己动手实现双向数据绑定? 如何把一个Model绑定到多个View?(观察者模式) 如何才能知道Model发生了变化?(脏值检测$watch与$digest) 如果Model是深层嵌套的结构,如何知道某个属性是不是变了?(对象深比较) 深层次的问题 :A和B两个方法互相watch对方的时候,如何避免发生“振荡”?(TTL机制) 绑定的过程中如何支持表达式?($parser与$eval自制JS版的编译器,Oh NO!) http://www.html-js.com/article/1863 68
使用AngularJS开发移动APP
69
开发移动APP的3种方式 Native APP WEB APP Hybrid APP 70
Native APP---优缺点 运行效率高 可调用各种设备资源 人力成本高 发布速度慢(AppStore确认的时间很长) 更新版本的问题(用户就是不更新!) 实现图文混排等功能有各种坑 71
一水儿的水果机,你司有不? 72
混乱不堪的Android平台---版本帝 4 个大版本, 14 个小版本 73
混乱不堪的Android平台---众多品牌 ...
74
混乱不堪的Android平台---各种分辨率
38种屏幕尺寸
75
混乱不堪的Android平台---众多厂商 1.BBK(步步高)-中国 2.OPPO(步步高旗下)-中国 3.lenovo(联想)- 中国 4.ZTE(中兴)-中国 5.HUAWEI(华为)-中国 6.时尚安卓手机 7.时尚安卓手机(12张) 8.MEIZU (魅族) - 中国 9.AUX(奥克斯)-中国 10.XIAOMI(小米公司)-中国 11.HTC(宏达国际电子)- 中国台湾 12.Acer(宏碁)-中国台湾 13.Motorola Mobility(摩托罗拉移动技术)- 美国 14.MOTOROLA(摩托罗拉)-中国 15.Samsung Electronics(三星电子)- 韩国 16.Sony Ericsson(索尼爱立信)-英国 17.LG Electronics(LG电子)-韩国 18.Lumigon (丹麦陆力更手机公司)- 丹麦 19.ARCHOS(爱可视)-法国 20.TOSHIBA(东芝)-日本 21.GiONEE 金立 22.SKYC (星天空数码)- 中国 22家大型厂商+无数山寨厂商 76
WEBAPP核心思路
打包 .ipa
.apk
.xap
77
常用打包工具:Phonegap http://phonegap.com/ 78
常用打包工具:Appcan http://www.appcan.cn/index.html
79
常用打包工具:appcelerator http://www.appcelerator.com/ 80
设计开发打包一体化工具Intel XDK 81
Android打包过程 npm 安装 Phonegap 下载 ADT Phonegap 调用 ADT 打包 就算开发存的WEB APP,还是要搭建原生环境的,因为要打包啊! 82
IOS打包过程 npm安装Phonegap 升级IOS和XCode IOS账户和一大堆配置 Phonegap调用XCode打包 各种Lisence,各种审核,各种矫情 就算开发存的WEB APP,还是要搭建原生环境的,因为要打包啊! 83
Phonegap暴露的设备API 84
常见WEB APP框架对比 优点:技术栈统一,学习成本低 缺点:低端安卓机存在性能问题 优点:各项技术架构都非常完善 缺点:学习成本高(与Extjs内核相同) 优点:衍生自jQuery,性能更好 缺点:有不少坑官方没有及时填起来 http://jquerymobile.com/ http://zeptojs.com/ 85
常见WEB APP框架对比
框架名称 jQuery Mobile zepto Sencha Touch GMU ionic 运行效率 学习成本 是否开源
低 高 中 中 高 低 低 高 高 高 是 是 是 是 是
备注
低端安卓机很卡; 体积小,只有10k; 只有内核,没有UI; ext-core内核,架构复杂 来自百度 内核是AngularJS 86
基于AngularJS的ionic http://ionicframework.com/ 87
WEBAPP最好的案例 88
WEB APP---优缺点 操作流畅程度不够(转场动画、列表滚动) 运行性能差 设备API不够 89
WEB APP---优缺点 致命缺陷:运行效率太差! 90
桌面平台上的Hybrid APP 外层是一个“壳子”,内部嵌入了浏览器内核 91
桌面平台上的Hybrid APP 92
桌面平台上的Hybrid APP 93
桌面平台上的Hybrid APP 94
移动平台上的Hybrid APP 95
移动平台上的Hybrid APP 96
移动平台上的Hybrid APP http://div.io/topic/560 97
Hybrid APP架构示意图 Android 外壳 WebView IOS外壳 UIWebView View切换 通讯服务 WebKit内核 HTML5/CSS3 Mobile UI控件库 通用组件 98
WEB调用Native时序图 99
Native调用WEB时序图 100
重要的参考资源 http://luics.com/demo/d2/index.html#/ 101
关于WebKit与WebView 102
Hybrid APP---优缺点 综合了开发效率和运行效率 发版本方便 运行效率中等(切换等交互效果) 需要写一点原生代码(至少2个平台) 103
Hybrid APP与WEB APP的核心不同点 Hybrid APP的本质是多WebView实例 WebApp本质是单WebView实例 104
TDD和前端自动化测试
105
TDD与前端自动化测试 TDD简介 前端单元测试 前端集成测试 106
单元测试runner-- Karma Pivotal Labs出品 原名:Testacular 2012年开源,2013年改名Karma 发音: ['kɑrm ə ] (中文模拟“卡马儿”) 含义:因果报应,因缘 Karma只是一款用来跑测试用例的runner http://karma-runner.github.io/0.12/index.html
107
单元测试工具-- Jasmine 发音:['d ʒ æzm ɪ n] 含义:茉莉花 作用:类似Java里面的JUnit,提供了一套语法,用来编写测试用例 http://jasmine.github.io/ Jasmine四个核心概念:分组、用例、期望、匹配,分别对应Jasmine的四种函数: describe(string,function) 这个函数表示分组,也就是一组测试用例。 it(string,function) 这个函数表示测试用例。 expect(expression) 表示期望expression这个表达式具有某个值或者具有某种行为。 to***(arg) 这个函数表示匹配。 108
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是通用的 109
一个完整的项目结构和演示 110
http://www.imooc.com/view/156 111
脚本娃娃-AngularJS2号群 112
Keep an open heart 感谢聆听
113