【问题标题】:Custom directive (like ng-repeat)自定义指令(如 ng-repeat)
【发布时间】:2016-06-14 03:35:29
【问题描述】:

我尝试了许多不同的方法来解决ng-repeat 的性能问题。 包括这里描述的东西:How to 'unwatch' an expression

我需要在页面上有一大组行,最多约 1000 行。每一行都包含相当多的东西。现在在我看来,使用ng-repeat 会很慢,我想我必须构建自己的自定义ng-repeat,或者我必须构建一个指令来构建表格中的每一行......我也不知道怎么办。你们能帮我吗?你能给我举几个例子吗?

【问题讨论】:

  • @blesh 在您提到的链接中提供了一个示例指令。尝试一下,让我们知道什么不起作用。
  • 在下面查看我的答案 我创建了一个 set-repeat,它一次遍历一组数据,并且不会向页面添加监视侦听器。我也在我的应用中使用它来解决内存问题。

标签: angularjs ng-repeat


【解决方案1】:

这是一个用

s 和
s 填充
的示例 ...

步骤 01 - 创建一个 widge.product.details.js

//绑定到$scope.details = [] //数组对象

angular.module('widget.product.details',[])
  .directive('productDetails',function(){
   return {
    template:'<dl class="dl-horizontal"></dl>',
    replace:true,
    restrict:'E',
    compile : function compile(tElement, tAttrs, transclude) {
     return {
      post: createProductDetails
     }
    }
   }
  });

var createProductDetails = function (scope, iElement, iAttrs, controller) {
    scope.$watch('details', function(newVal, oldVal) {
    angular.forEach(newVal, function(v,k){
        iElement.append( angular.element('<dt>'+v.dt+'</dt><dd>'+v.dd+'</dd>') );
        });
    });
}

步骤 02 - 创建您的 html

<div class="span7" ng-controller="ProductInfoCtrl">
 <product-details></product-details>
</div>

步骤 03 - 创建 app.product.js

function ProductInfoCtrl($scope) {
 $scope.details = [
                   {dt:'condition',dd:'brand new'},
                   {dt:'year bought',dd:'3 years ago'},
                   ]
}

【讨论】:

  • 使用forEach() 循环会不会更好地提高性能,将其全部存储在一个字符串中,然后在forEach() 之后执行一个append()
  • 也许,听起来是个好主意。我会相信一个基准......:D
  • 仅供参考:使用 compile { post: .. } 与使用 link: function(scope, element, attributes) 相同
【解决方案2】:
angular.module('setRepeat',[]).directive('setRepeat', function () {

  return {
    transclude: 'element',
    priority: 1000,
    compile: compileFun
  };

  function compileFun(element, attrs, linker) {
      var expression = attrs.setRepeat.split(' in ');
      expression = {
        child : expression[0],
        property : expression[1]
      };

      return {
        post: repeat
      };

      function repeat(scope, iele, iattrs /*, attr*/) {
        var template = element[0].outerHTML;
        var data = scope.$eval(expression.property);
        addElements(data,scope,iele);

        return;

        function makeNewScope (index, expression, value, scope, collection) {
          var childScope = scope.$new();
          childScope[expression] = value;
          childScope.$index = index;
          childScope.$first = (index === 0);
          childScope.$last = (index === (collection.length - 1));
          childScope.$middle = !(childScope.$first || childScope.$last);

          /**
          *
          * uncomment this if you want your children to keep listening for changes
          *
          **/

          //childScope.$watch(function updateChildScopeItem(){
            //childScope[expression] = value;
          //});
          return childScope;
        }

        function addElements (collection, scope, insPoint) {
          var frag = document.createDocumentFragment();
          var newElements = [], element, idx, childScope;

          angular.forEach(data, function(v,i){
            childScope = makeNewScope(i,expression.child,v,scope,collection);
            element = linker(childScope, angular.noop);
            newElements.push(element);
            frag.appendChild(element[0]);
          });

          insPoint.after(frag);
          return newElements;
        }
      }
  }

});

【讨论】:

  • 您好,您如何为 setRepeat 表达式设置监视?我的意思是当property 发生变化时如何更新孩子?
  • @supersan 这就是它不会改变的重点......所以只在不需要更新的东西上使用它。另外仅供参考,角度团队最终列出并创建了一次绑定语法,因此您不再需要它了。您现在可以执行 ng-repeat="item in ::list" 它将绑定重复一次并停止收听
  • 哦好吧..你是对的!实际上,我偶然发现了 Google 提出的这个问题,我正在寻找一种方法来创建自定义 ng-repeat(用于我自己的数据表,如指令)。无论如何,感谢您的澄清。
【解决方案3】:

angularJS 中自定义 ngReapeat 指令的简单代码:

   <!DOCTYPE html>
   <html>
    <head>
       <script type='text/javascript' src='angular.min.js'></script>    
    </head>
    <body ng-app="customNgReapeat">
      <div ng-controller='ProductInfoCtrl'>
        <div custom-repeat></div>
      </div>    
    </body>
  </html>

JS 代码

    var csREapeat = angular.module('customNgReapeat', [])
      .directive('customRepeat', function() {
        return {
          restrict: 'A',
          link: function(scope, iElement, iAttrs, controller) {
            angular.forEach(scope.details, function(v, k) {
              iElement.append(angular.element('<div>' + v.name + '</div>             <div>' + v.address + '</div>'));
            });
          }
        };
      })

 function ProductInfoCtrl($scope) {
   $scope.details = [
      {name: 'Nidhi', address: 'India-Gurgaon'},
      {name: 'Khushi', address: 'India-Ghazipur'}
   ];
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-02-26
    • 1970-01-01
    • 1970-01-01
    • 2015-03-06
    • 2013-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多