1

我有一个使用 ng-repeat 生成大量 html input[type="radio"] 的指令。它们中的每一个都分配了许多属性。

基本上:

<div ng-repeat"day in days">
  <label ng-repeat="slot in day.slots">
    <input type="radio" class="{{slot.class}}" value="{{slot.value}}" ng-disabled="{{slot.disabled}}">
  </label>
</div>

问题是 Angular 为每个输入元素的每个属性添加了一个观察者,它消耗了大量资源。如果不改变,属性就不会days改变。有什么方法可以使属性静态并仍然使用 ng-repeat?或者我必须以其他方式生成模板吗?在那种情况下,我将如何做并且在更改时仍然重新渲染它days

更新:澄清它不仅仅是类属性

4

1 回答 1

0

尝试使用ng-class.

<input type="radio" ng-class="slot.class" />

观察者仍然是绑定的,但是每次摘要发生时都不会设置类属性,只有当值发生slot.class变化时。

编辑:更新以反映原始海报想要的内容。

我不确定这是否是一个好的做法,但您可以尝试编写一个指令,通过取消注册所有观察者来生成一个“哑”模板。这样,只有当 watch 语句的结果发生变化时,您才会更新模板。

像这样的东西:

module.directive('shallowWatch', function($compile){
    return {
        compile : function(tElement, tAttrs){
            var templateFN = $compile(tElement.html());
            tElement.empty();
            return function(scope, element, attrs){
                var childScope;
                scope.watch(attrs.shallowWatch, function(){
                    element.empty();
                    if(childScope){
                        childScope.$destroy();
                    }
                    childScope = scope.$new();
                    element.append(templateFn(childScope));
                    traverseScope(childScope, function(scope){
                        scope.$$watchers = [];
                    });
                });
            };
        }
    };

    function traverseScope(target, fn){
        var current, next;
        current = target;
        do {
            fn.apply(current, [current]);

            //depth-first traversal pulled from angularjs core
            if (!(next = (current.$$childHead || (current !== target && current.$$nextSibling)))) {
                while(current !== target && !(next = current.$$nextSibling)) {
                    current = current.$parent;
                }
            }
        } while ((current = next));
    }
});

你会像这样使用它:

<div shallow-watch="days">
    <div ng-repeat"day in days">
      <label ng-repeat="slot in day.slots">
        <input type="radio" class="{{slot.class}}" value="{{slot.value}}" ng-disabled="{{slot.disabled}}">
      </label>
    </div>
</div>
于 2013-07-11T10:25:19.270 回答