Смысл в том, что часто на странице очень много элементов для которых нужно выпонить биндинг данных только один раз используя данные моделей которые не изменяются, например:
<h1 ng-bind="l10n.main_title"></h1>
<a ng-href="/edit/{{user.id}}" ng-bind="user.name"></a>
Эти и другие стандартные директивы любезно будут проверять не изменилось ли значение выражения при каждом $digest. Исправить ситуацию можно набором довольно простых кастомных директив, например для текста:
app.directive(staticText', function() { return { restrict: "A" link: function(scope, element, attrs) { element.text(scope.$eval(attrs.customText)); } }; })
<h1 custom-text="l10n.main_title"></h1>
Результат — минус один $watch.
Выдумывать свой велосипед конечно же не нужно, на GitHub лежат два достойных модуля:
Первый ($watch fighters) совсем простой, включает в себя такие директивы:
- set-title
- set-href
- set-text
- set-html
- set-class
- set-if
Второй же (Bindonce) интереснее, т.к. разработчики подумали о том, что данные для биндинга могут быть недоступны в момент рендеринга шаблона директивы (например, они подгружаются ajax-запросом). Выглядит это так:
<div bindonce="User"> <h1 bo-text="User.name"></h1> </div>
Для родительской директивы bindonce создается времменый $watch, когда значение переданной в неё переменной становится отличным от undefined запускаются вложенные bo-* директивы, а временный $watch удаляется.
Модуль Bindonce включает:
- bo-if
- bo-show
- bo-hide
- bo-text
- bo-html
- bo-href
- bo-src
- bo-class
- bo-alt
- bo-title
- bo-id
- bo-style
- bo-value
- bo-attr bo-attr-foo
Более подробно можно почитать на странице репозитория, там довольно развернутый readme.
На последок приведу функцию, которую нашел здесь. Она примерно подсчитывает общее количество $watch’еров на странице.
(function () { var root = $(document.getElementsByTagName('body')); var watchers = []; var f = function (element) { if (element.data().hasOwnProperty('$scope')) { angular.forEach(element.data().$scope.$$watchers, function (watcher) { watchers.push(watcher); }); } angular.forEach(element.children(), function (childElement) { f($(childElement)); }); }; f(root); console.log(watchers.length); })();
Ради интересы можно сравнить количество до и поле внедрения zero-watch директив.
Надеюсь кому то пригодится. Спасибо.
ссылка на оригинал статьи http://habrahabr.ru/post/208768/
Добавить комментарий