30
AngularJS Data Binding Ticore Shih 2013/08/05 https://github.com/Ticore/ng-data-binding-sample

AngularJS Data Binding

Embed Size (px)

Citation preview

Page 1: AngularJS Data Binding

AngularJS Data Binding

Ticore Shih 2013/08/05

https://github.com/Ticore/ng-data-binding-sample

Page 2: AngularJS Data Binding

Data Binding 定義

• 來源資料變化,目的資料對應變化 • Observer design pattern

Subject

Observer 1

Update Observer 2

Observer 3

Page 3: AngularJS Data Binding

Data Binding 使用情境

• Frontend <-> Backend

• View <-> Model

MDV UI Data Binding

Page 4: AngularJS Data Binding

Data Binding 組成

Source model

Destination model

Trigger Listener / Watcher

UI Template Expression

Page 5: AngularJS Data Binding

AngularJS Data Binding Example

<!DOCTYPE HTML> <html> <head><meta charset="UTF-8"></head>

<body ng-app ng-init="txt='Hello';"> <p ng-bind="this.txt"></p> <input type="text" ng-model="txt"></input> <script src="../libs/angular-1.1.5.js"> </script> </body> </html>

簡報者
簡報註解
0_binding_example/00_simple_binding.html
Page 6: AngularJS Data Binding

Data Binding 概念

• 語意簡單明確

• 宣告式而非命令式

–無順序、無副作用

• 依賴反轉

Page 7: AngularJS Data Binding

太難寫的東西沒資格稱為 「Data Binding」

Code-behind required

Complex directive, expression

Page 8: AngularJS Data Binding

Data Binding 各種作法

• Pre-compile Flex, zk, backbase, ...

• Runtime compile

Angular.js, Knockout.js, Ember.js, ...

• Native support

ECMA 6 : Object.observe() HTML's New Template Tag http://www.html5rocks.com/en/tutorials/webcomponents/template/

Web Component – MDV http://www.polymer-project.org/

Page 9: AngularJS Data Binding

Data Binding Check Mode

Dirty Check

• 被動檢查 • Any Object, Function • 通常語法較簡潔 • 容易產生無窮迴圈 • 影響範圍廣泛

Change Event

• 主動發出 • Bindable, Observable • 通常語法較複雜 • 容易產生大量事件 • 影響範圍有限

Page 10: AngularJS Data Binding

Data Binding Expression Type

• Full function language

• Partial function language

• String interpolation <p>txt : {{ txt }}</p>

• Domain specific language ng-repeat="i in array"

Page 11: AngularJS Data Binding

AngularJS Expression

• Against scope • Forgiving

{{ a.b.c }}

• No control flow • No declaration • Filter pipeline

number, currency, date, json, orderBy, filter, limitTo, lowercase, uppercase

簡報者
簡報註解
0_binding_example/01_scope_filter_ternary.html
Page 12: AngularJS Data Binding

AngularJS $digest Cycle __________________ _____________________________________

/ Native \ / Javascript \ | | | ___________________________ | | | | / AngularJS \ | | ___________ | | | | | | | | | | | | | | |Event Queue|--------> $apply(fn) ----> fn() | | | | (Wait) | | | | | | | | |___________| | | | V | | | ^ | | | .----->----. | | | | | | | ___/ $evalAsync \___ | | | | Event Loop | / \ queue / \ | | | | | | | | '----<-----' | | | | | | | | ^ $digest loop | | | | | | | | | (TTL = 10) V | | | _____|_____ | | | | .----->----. | | | | | | | | | \___/ $watch \___/ | | | | DOM Render|<---------------------\ list / | | | |___________| | | | '----<-----' | | | | | \___________________________/ | \__________________/ \_____________________________________/

Page 13: AngularJS Data Binding

AngularJS $digest Trigger

• Bootstrap • $timeout • $http done • Dom event

– click, submit, change, link, mouse events keyboard events.

• Url change

Page 14: AngularJS Data Binding

AngularJS Watchers

var unwatch = $scope.$watch(expr, listener, equality);

• Dirty check

– 不斷執行 Expression 直到結果一樣

• Object equality

– 參考相等 or 資料相等 – 忽略 '$' 開頭屬性

簡報者
簡報註解
0_binding_example/02_watcher.html 0_binding_example/03_dirty_check.html 0_binding_example/04_object_equality.html
Page 15: AngularJS Data Binding

$digest Loop 進入點

• $apply() –執行表示式,例外處裡 – scope : $rootScope – $$phase : '$apply'

• $digest()

– scope : $scope – $$phase : '$digest'

Page 16: AngularJS Data Binding

$apply() Pseudo-Code function $apply(expr) { try { return $eval(expr); // '$apply' phase } catch (e) { $exceptionHandler(e); } finally { $root.$digest(); // '$digest' phase } }

Page 17: AngularJS Data Binding

Enter $digest Loop • url change

if (!$rootScope.$$phase) { $rootScope.$digest(); }

• http done

if (!$rootScope.$$phase) { $rootScope.$apply(); }

Page 18: AngularJS Data Binding

Expression Evaluation

$eval(expr, locals) vs. $evalAsync(expr) –均不會觸發 $digest loop –均同一次 event loop 執行 –是否直接回傳結果 – Inject locals

Page 19: AngularJS Data Binding

Data Binding Trick

• Multiple trigger

$scope.$watch( "a + b + c + d", function() { ...... } );

簡報者
簡報註解
1_binding_trick/00_multi_trigger.html
Page 20: AngularJS Data Binding

Data Binding Trick

• Cascade binding

a b c d \ / \ / ab cd \ /

abcd

簡報者
簡報註解
1_binding_trick/01_cascade.html 1_binding_trick/01_cascade_lazy.html
Page 21: AngularJS Data Binding

Data Binding Trick

• Register $digest

$scope.$watch( function() { ...... } );

Page 22: AngularJS Data Binding

Data Binding Performance

• Human are:

– Slow (> 50 ms) – Limited (< 2000 pieces)

http://goo.gl/JeJNY

• GUI 30/60 FPS -> 33.3/16.6 ms

Page 24: AngularJS Data Binding

Data Binding 效能改善 • GUI 效果不要使用 Binding

• 謹慎使用 $timeout

• 輕量化 Expression

• 計算放在 Listener

• 減少 Watchers 數量

簡報者
簡報註解
2_binding_opt/00_opt_gui0.html 2_binding_opt/00_opt_gui1.html 2_binding_opt/01_opt_timeout0.html 2_binding_opt/01_opt_timeout1_fps.html 2_binding_opt/01_opt_timeout2_fix.html 2_binding_opt/02_opt_light_exp0.html 2_binding_opt/02_opt_light_exp1.html 2_binding_opt/02_opt_light_exp2.html
Page 25: AngularJS Data Binding

3rd-party Binding Directive

• One time data binding – Bindonce

https://github.com/Pasvaz/bindonce

– $watch fighters https://github.com/abourget/abourget-angular

• Faster repeat

– dfa-stable-repeat http://www.youtube.com/watch?v=g8xkax9Z_sQ http://goo.gl/M9pIjA

Page 26: AngularJS Data Binding

Pause Data Binding

• Unpause state

–計算結果存入快取

• Pause state

–回傳上次快取資料

簡報者
簡報註解
3_binding_lazy/00_pause_binding.html
Page 27: AngularJS Data Binding

Lazy Data Binding

減少評估與執行次數

– 延緩第一次執行 (bypass two $digest / expr) – 給定時間範圍內最多執行一次 – 滿足最後一次 dirty check – 限定範圍 $scope.$digest()

https://github.com/Ticore/ngLazyBind

簡報者
簡報註解
3_binding_lazy/01_lazy_binding0.html 3_binding_lazy/01_lazy_binding1.html 3_binding_lazy/01_lazy_binding2.html
Page 28: AngularJS Data Binding

Data Binding Error

Error: 10 $digest() iterations reached. Aborting!

改善方式

– $rootScopeProvider.digestTtl – TTL 無效 -> 程式邏輯有問題

簡報者
簡報註解
4_binding_error/00_bind_error.html 4_binding_error/00_bind_fix.html 4_binding_error/01_repeat_error0.html 4_binding_error/01_repeat_error0_delay.html 4_binding_error/01_repeat_error0_lazy.html 4_binding_error/02_repeat_error1.html 4_binding_error/02_repeat_error1_fix.html 4_binding_error/02_repeat_error1_watch.html 4_binding_error/03_two_way_error.html 4_binding_error/03_two_way_lazy.html
Page 29: AngularJS Data Binding

Data Binding 範疇終點 • ngNonBindable

<p ng-non-bindable> i : {{ i }} </p>

• Terminal directive function factory() { return { terminal: true }; }

簡報者
簡報註解
5_binding_non/00_ng_non_bind.html
Page 30: AngularJS Data Binding

Thanks!