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!

AngularJS Data Binding

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