19

AngularJS: what is underneath the hood

  • Upload
    da-14

  • View
    231

  • Download
    0

Embed Size (px)

Citation preview

Page 1: AngularJS: what is underneath the hood
Page 2: AngularJS: what is underneath the hood

- the less routine code the happier developers- good application structure two-way data binding- directives- testability- active community / cool documentation, etc...

Page 3: AngularJS: what is underneath the hood

var btn = document.getElementById("myBtn");

btn.addEventListener("click", onClick);

function onClick(evt) {

// some code

}

Page 4: AngularJS: what is underneath the hood

<button ng-click=”onClick($event)”></button>

element.on(‘click’, function(event){

var callback = function(){

fn(scope, {$event: event});

} scope.$apply(callback);

})

Page 5: AngularJS: what is underneath the hood

<span>{{myModel}}</span>

function myController($scope, $timeout) {

$scope.myModel = ‘value1’;

setTimeout(function(){

$scope.myModel = ‘value2’;

}, 500);

$timeout(function(){

$scope.myModel = ‘value2’;

}, 500);

}

Page 6: AngularJS: what is underneath the hood

scope.$watch(‘someModel2’,

callback);

{{someModel}}, ng-bind

ng-repeat, ng-model..

$timeout(fn) с нулевой

задержкой

scope.$evalAsync(fn)

$watch list $evalAsync list

Page 7: AngularJS: what is underneath the hood

step 1:function Scope() {}

step 2:function Scope() { this.$$watchers = [];}

step 3:Scope.prototype.$watch = function(watchFn, listenerFn) { var watcher = { watchFn: watchFn, listenerFn: listenerFn }; this.$$watchers.push(watcher);};

$watchList implementation

Page 8: AngularJS: what is underneath the hood

step 4:Scope.prototype.$digest = function() { _.forEach(this.$$watchers, function(watch) { watch.listenerFn(); }); };

step 5: Scope.prototype.$digest = function() { var self = this; _.forEach(this.$$watchers, function(watch) { var newValue = watch.watchFn(self); var oldValue = watch.last; if (newValue !== oldValue) { watch.listenerFn(newValue, oldValue, self); } watch.last = newValue; }); };

Page 9: AngularJS: what is underneath the hood

...$scope.$watch(‘myModel’, function(){ alert(‘My model was changed’);});

$scope.$watch(‘yourModel’, function(){ scope.myModel = ‘someValue’;});...

<input type=”text” ng-model=”yourModel” />

Page 10: AngularJS: what is underneath the hood

Scope.prototype.$digest = function() { var self = this; var dirty; do {

dirty = false; _.forEach(this.$$watchers, function(watch) { var newValue = watch.watchFn(self); var oldValue = watch.last; if (newValue !== oldValue) { watch.listenerFn(newValue, oldValue, self);

dirty = true; } watch.last = newValue; });

} while (dirty); };

DIRTY CHECK

Page 11: AngularJS: what is underneath the hood

step 1:function Scope() { this.$$watchers = []; this.$$asyncQueue = [];}

step 2: Scope.prototype.$evalAsync = function(expr) { var obj = {scope: this, expression: expr}; this.$$asyncQueue.push(obj);};

step 3:Scope.prototype.$digest = function() { while (this.$$asyncQueue.length) { var asyncTask = this.$$asyncQueue.shift(); this.$eval(asyncTask.expression); } ...};

$watchList implementation$evalAsync implementation

function myCtrl($scope, $rootScope) {

$scope.myModel = ‘value1’;

$scope.$evalAsync(function(){

console.log($scope.myModel);

});

$scope.myModel = ‘value2’;

}

Page 12: AngularJS: what is underneath the hood

$scope.$apply vs $scope.$digest

<body ng-app=”myApp”>{{rootMessage}} <div ng-controller=”myCtrl”>{{childMessage}}</div></body>function myCtrl($scope, $rootScope) { $rootScope.rootMessage = ‘root message’; $scope.childMessage = ‘child message’;

setTimeout(function(){$rootScope.rootMessage = ‘new root message’;

$scope.childMessage = ‘new child message’; $scope.apply(); // both model are re-rendered $scope.digest(); // only childMessage

}, 5000); }

Page 13: AngularJS: what is underneath the hood

setTimeout(function(){ $scope.apply(function(){//some code});}, 5000); }

$apply: function(expr) { try { return this.$eval(expr); } catch (e) { $exceptionHandler(e); } finally { try { $rootScope.$digest(); } catch (e) { $exceptionHandler(e); throw e; } }}

Page 14: AngularJS: what is underneath the hood

SOME OPTIMIZATION TIPS

- minimize watchers: - limit DOM filters

- use onetime binding when possible ng-bind=”::myModel” ng-repeat=”item in ::items” or bindonce if Angular < 1.3

- lightweight watch-functions and callbacks in watchers- ng-repeat=”item in items track by item.id” - $watchCollection instead of $watch with 3rd parameter equaled true- debounce ng-model <input ng-model=”myModel” ng-model-

options=”{debounce: 500}” />- use native JS or lodash (for example, simple ‘for’ loop instead of

angular.forEach )- use directive ng-bind instead of {{}};

Page 15: AngularJS: what is underneath the hood

$parse

$scope.$watch(function() {

return $scope.myModel;

}, callback);

$scope.$watch(‘myModel’, callback);

$watch: function(watchExp, listener, objectEquality){

var get = $parse(watchExp);...

}

$eval: function(expr, locals) {

return $parse(expr)(this, locals);

},

Page 16: AngularJS: what is underneath the hood

DEPENDENCY INJECTION IN ANGULAR

Dependency Injection is a software design pattern in which an object is given its

dependencies, rather than the object creating them itself.

angular.module(‘myApp’, []);

angular.module(‘myApp’)

.controller(‘myController’, myController);

function myController($scope, $timeout, myService) { // some code goes here }

function myController($timeout, $scope, myService) { // some code goes here }

Page 17: AngularJS: what is underneath the hood

ISSUES WITH IMPLICIT DEPENDENCESBefore minification:

angular.module(‘myApp’, []);

angular.module(‘myApp’)

.controller(‘myController’, myController);

function myController($scope, $timeout, myService) { // some code goes here }

After:

angular.module(‘myApp’,[]);angular.module(‘myApp’).controller(‘myController’,myController);function myController(l,o,p){...}

Page 18: AngularJS: what is underneath the hood

SOLUTIONSInline array annotation

$inject property annotation

angular.module(‘myApp’)

.controller(‘myController’, [‘$scope’, ‘myService’, myController]);

function myController($scope, myService) { ...}

angular.module(‘myApp’).controller(‘myController’, myController);

myController.$inject = [‘$scope’, ‘myService’];

function myController($scope, myService) { ...}

Page 19: AngularJS: what is underneath the hood

ОЙ, ВСЕ!