Download - AngularJS Data Binding
AngularJS Data Binding
Ticore Shih 2013/08/05
https://github.com/Ticore/ng-data-binding-sample
Data Binding 定義
• 來源資料變化,目的資料對應變化 • Observer design pattern
Subject
Observer 1
Update Observer 2
Observer 3
Data Binding 使用情境
• Frontend <-> Backend
• View <-> Model
MDV UI Data Binding
Data Binding 組成
Source model
Destination model
Trigger Listener / Watcher
UI Template Expression
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>
Data Binding 概念
• 語意簡單明確
• 宣告式而非命令式
–無順序、無副作用
• 依賴反轉
太難寫的東西沒資格稱為 「Data Binding」
Code-behind required
Complex directive, expression
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/
Data Binding Check Mode
Dirty Check
• 被動檢查 • Any Object, Function • 通常語法較簡潔 • 容易產生無窮迴圈 • 影響範圍廣泛
Change Event
• 主動發出 • Bindable, Observable • 通常語法較複雜 • 容易產生大量事件 • 影響範圍有限
Data Binding Expression Type
• Full function language
• Partial function language
• String interpolation <p>txt : {{ txt }}</p>
• Domain specific language ng-repeat="i in array"
AngularJS Expression
• Against scope • Forgiving
{{ a.b.c }}
• No control flow • No declaration • Filter pipeline
number, currency, date, json, orderBy, filter, limitTo, lowercase, uppercase
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 / | | | |___________| | | | '----<-----' | | | | | \___________________________/ | \__________________/ \_____________________________________/
AngularJS $digest Trigger
• Bootstrap • $timeout • $http done • Dom event
– click, submit, change, link, mouse events keyboard events.
• Url change
AngularJS Watchers
var unwatch = $scope.$watch(expr, listener, equality);
• Dirty check
– 不斷執行 Expression 直到結果一樣
• Object equality
– 參考相等 or 資料相等 – 忽略 '$' 開頭屬性
$digest Loop 進入點
• $apply() –執行表示式,例外處裡 – scope : $rootScope – $$phase : '$apply'
• $digest()
– scope : $scope – $$phase : '$digest'
$apply() Pseudo-Code function $apply(expr) { try { return $eval(expr); // '$apply' phase } catch (e) { $exceptionHandler(e); } finally { $root.$digest(); // '$digest' phase } }
Enter $digest Loop • url change
if (!$rootScope.$$phase) { $rootScope.$digest(); }
• http done
if (!$rootScope.$$phase) { $rootScope.$apply(); }
Expression Evaluation
$eval(expr, locals) vs. $evalAsync(expr) –均不會觸發 $digest loop –均同一次 event loop 執行 –是否直接回傳結果 – Inject locals
Data Binding Trick
• Multiple trigger
$scope.$watch( "a + b + c + d", function() { ...... } );
Data Binding Trick
• Cascade binding
a b c d \ / \ / ab cd \ /
abcd
Data Binding Trick
• Register $digest
$scope.$watch( function() { ...... } );
Data Binding Performance
• Human are:
– Slow (> 50 ms) – Limited (< 2000 pieces)
http://goo.gl/JeJNY
• GUI 30/60 FPS -> 33.3/16.6 ms
Data Binding 效能測試
• Chrome profiler
https://developers.google.com/chrome-developer-tools/docs/cpu-profiling
• Batarang tool
https://chrome.google.com/webstore/search/angularjs-batarang
Data Binding 效能改善 • GUI 效果不要使用 Binding
• 謹慎使用 $timeout
• 輕量化 Expression
• 計算放在 Listener
• 減少 Watchers 數量
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
Pause Data Binding
• Unpause state
–計算結果存入快取
• Pause state
–回傳上次快取資料
Lazy Data Binding
減少評估與執行次數
– 延緩第一次執行 (bypass two $digest / expr) – 給定時間範圍內最多執行一次 – 滿足最後一次 dirty check – 限定範圍 $scope.$digest()
https://github.com/Ticore/ngLazyBind
Data Binding Error
Error: 10 $digest() iterations reached. Aborting!
改善方式
– $rootScopeProvider.digestTtl – TTL 無效 -> 程式邏輯有問題
Data Binding 範疇終點 • ngNonBindable
<p ng-non-bindable> i : {{ i }} </p>
• Terminal directive function factory() { return { terminal: true }; }
Thanks!