为什么其它所有前端框架都不实现双向数据绑定

Download Report

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