【问题标题】:Using ng-class with a function call - called multiple times将 ng-class 与函数调用一起使用 - 多次调用
【发布时间】:2023-03-23 15:32:01
【问题描述】:

我正在使用 Ionic,并希望根据数据动态更改 <ion-list> 中每个项目的背景颜色。我想我会通过函数调用来返回正确的类来做到这一点

<ion-list>
  <ion-item ng-repeat="singleCase in allCases" ng-class="getBackgroundColour(singleCase)" class="item-avatar">
    <h2>{{singleCase.date}}</h2>
    <p>{{singleCase.caseType}}</p>
  </ion-item>
</ion-list>

这是目前的控制器

  .controller('AllCasesCtrl', ['$scope', '$log', 'dummyData', function($scope, $log, dummyData) {
    $scope.allCases = dummyData.cases;

    $scope.getBackgroundColour = function(singleCase){

      $log.log("getBackgroundColour called...singleCase type: " + singleCase.speciality);

      var colourMap = {
        speciality1: "speciality1Class",
        speciality2: "speciality2Class",
        speciality3: "speciality3Class"
      };

      return colourMap[singleCase.speciality];
    };

  }])

在检查控制台时,列表中的每个 &lt;ion-item&gt; 都会调用 getBackgroundColour() 函数 7 次。为什么会这样,我应该避免在ng-class 中使用函数调用吗?

【问题讨论】:

    标签: angularjs ionic-framework


    【解决方案1】:

    AngularJS 与dirty checking 一起工作:它需要调用函数每个周期 以确保它不会返回新值并且不需要更新 DOM。

    这是框架典型过程的一部分,调用像您这样简单的函数不应对性能产生任何负面影响。代码的可读性和可测试性在这里更为重要,因此请将逻辑保留在控制器中。

    然而,要做的一件简单的事情就是将colourMap 的声明(它是一个常量)移到您的函数之外:

    var colourMap = {
        speciality1: "speciality1Class",
        speciality2: "speciality2Class",
        speciality3: "speciality3Class",
    };
    
    $scope.getBackgroundColour = function(singleCase) {
      return colourMap[singleCase.speciality];
    };
    

    【讨论】:

    • 假设我有 100 个生成的元素,它将调用我的函数 100*100 = 10 000 次。还有另一种绕过脏检查系统的解决方案吗?作为 AngularJS 的新手,我看到控制器之间的继承可用于存储数据,但我不知道这是否是“最佳实践”。有人可以帮我解释一下吗?谢谢
    • @Alex 你的微积分中的第二个“100”来自哪里?如果您知道表达式不会更改(即lazy one-time binding),则只能评估一次表达式,但您不能“绕过”脏检查系统。没有它,你怎么知道你的价值观发生了变化?
    • 是的,我写的有点太快了。我想说该函数被调用 (100 + 99 + 98 + 97 ... + 2 + 1) 次(以我的 100 个元素为例)。通过绕过肮脏的检查系统,这是我糟糕的英语出卖了我。我想问是否有一种方法可以通过使用另一种方法只检查一次值。最后,非常感谢你懒惰的一次性绑定,我要看看这个。
    • @Alex 我不明白:如果你有 100 个元素,该函数只会被调用 100 次,除非你一个接一个地在相应的数组中添加新项目,至少有一个之间的消化循环。
    • 显然我的第一个公式是正确的:我会向你解释我为什么这么说。我的角度控制器中有一组 3 个对象。在 HTML 模板中,我使用 ng-repeat 循环遍历这个数组。除了 ng-repeat 指令,我还添加了一个 ng-class 指令,其中包含一个函数。喜欢getCssClass({{ element.type }})。在这个函数中,我放置了一个 console.log,每个元素显示两次。所以我有 6 个控制台输出,而不是我应该有的 3 个。我的解释够清楚吗? (再次对不起我的英语)
    【解决方案2】:

    只要您的列表不是很大,您的方式就可以了。话虽如此,如果您使用 angular 1.3 并且想要减少调用次数,您可以将 ng-class 更改为 ng-class="::getBackgroundColour(singleCase)"。这适用于一次绑定,因此一旦值稳定,它将不会再次检查。这很可能意味着每个项目有两次调用。

    【讨论】:

    • 谢谢,一定要去看看这个。课程应该保持非常稳定,所以我可以试试这个。但是,如果用户去更改数据,则需要更新类...使用一次性绑定会破坏这一点吗?
    • 只要你不对 allCases 变量使用一次性绑定,它就会再次调用它,因为 ng-repeat 将执行并创建新的 dom 元素
    猜你喜欢
    • 1970-01-01
    • 2013-04-03
    • 2017-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-12
    • 2021-11-24
    • 2011-09-19
    相关资源
    最近更新 更多