Yet another $parse usage

в 2:49, , рубрики: Песочница, метки: , ,

Приветствую, читатель.

Сегодня я прочитал статью-перевод, которая меня слегка разочаровала. Во-первых, содержанием (нет, я не виню переводчика). Во-вторых, тем, что я не увидел тех трюков, которые я хотел бы увидеть.

Поэтому, хочу поделиться с вами теми возможностями $parse, которые я знаю.

$scope.$eval

Если у вас есть вызов $scope.$eval с одним и тем же выражением в цикле — однозначно меняйте на $parse.

for (var i = 0; i < 1e5; ++i) {
  $scope.$eval('my.expr'); // слоупок
}

var expr = $parse('my.expr');
for (var j = 0; j < 1e5; ++j) {
  expr($scope); // флэш
}

$scope.$watch в директивах

Когда я узнал об этой технике, то моя челюсть устремилась к полу. Читаем комментарии к коду.

// slow example
app.directive('myDir', function() {
  return {
    link: function(scope, elem, attrs) {
      // Медленно
      scope.foo = scope.$eval(attrs.foo);
      
      // Медленно
      scope.$watchCollection(attrs.list, function(list) {
        // Some code
      });
    }
  };
});

// fast example
app.directive('myDir', function($parse) {
  return {
    compile: function(tElem, tAttrs) {
      // compile вызывается один раз для элемента, в котором "вызов" директивы
      var fooExpr = $parse(tAttrs.foo),
          listExpr = $parse(tAttrs.list);
          
      // а вот post-link для каждого элемента
      return function postLinkFn(scope) {
        // Однако $parse быстро получает значение
        scope.foo = fooExpr(scope);
        
        // Опять же, $parse хорошо выступает в качестве watchExpr
        scope.$watchCollection(listExpr, function(list) {
          // Some code
        });
      }
    }
  };
});

Последний трюк — использование $parse в compile функции директивы, с дальнейшим вызовом в link. Очень хорошо сказывается на производительности.

Надеюсь, что приоткрыл для кого-то из вас завесу тайны, и теперь вы будете использовать сервис $parse в благих целях.


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js