【问题标题】:When exactly is ng-checked called究竟何时调用 ng-checked
【发布时间】:2015-08-11 18:15:03
【问题描述】:

在使用 AngularMaterial 时,我有 ng-checked 这样的:

<md-list>
    <md-list-item ng-repeat="option in options">
       <p> {{ option }} </p>
       <md-checkbox class="md-secondary" aria-label="{{$index}}" ng-checked="exists($index)" ng-click="toggle($index)"></md-checkbox>
    </md-list-item>
</md-list> 

我的存在函数:

$scope.exists = function (optionNum) {
    console.log('Inside $scope.exists. option: '+optionNum);
};

我的计时器:

function updateTimer() {
    var onTimeout = function(){
      mytimeout = $timeout(onTimeout,1000);
    }
    var mytimeout = $timeout(onTimeout,1000);
}

这样,$scope.exists 函数每秒都会被调用一次。有人可以解释一下ng-checked$timeout 的关系吗?以及如何避免这种情况?

【问题讨论】:

    标签: javascript angularjs checkbox angular-material


    【解决方案1】:

    ng-checked,就像许多 Angular 的指令一样,都是基于手表的。每当调用摘要循环时,它都会评估所有观察者(您正在使用的函数就是其中之一)。因此,每次 $timeout 评估它都会开始一个新的 $digest 循环并评估所有观察者。这是使用控制器和指令中的所有数据更新视图的“魔法”的一部分。

    如果您让函数变得复杂,或者让观察者数量众多,那么观察者可能会成为性能问题。通常最好有简单的逻辑来快速返回 true 或 false,并避免对所有内容设置监视。

    【讨论】:

    • 我只是想知道自己,他们甚至没有时间阅读它!
    • 已更新,从我所读到的所有内容来看,只要您保持快速且数量合理,观察者就可以了
    【解决方案2】:

    一个词的原因是:digest cycle。由于您的函数绑定到视图,每次摘要循环发生时,这些表达式都会作为脏检查的一部分进行评估,以确保是否需要更新相应的 DOM。这与角度材料无关,它是核心角度实现。现在,在您的情况下,您正在无限调用 $timeout,这意味着在每次超时执行后,digest 循环恰好执行脏检查。

    现在你所拥有的一切都很好,但是当你 bind 一个 DOM 函数(作为视图绑定、插值或属性状态属性甚至 DOM 过滤器的一部分 - 当然事件很好)时,你应该是 意识到随着应用程序的增长,您不会意外或有意地对该功能执行大量操作,这会减慢整个应用程序的速度,并且当应用程序变大并开始出现问题时将难以重构和诊断正在发生。尽可能绑定到属性而不是函数。请注意,即使您绑定了一个属性,$parse 仍然会在其上创建一个 getter 并将其添加到 $$watchers 队列以在每个摘要周期进行脏检查,但不同之处在于它是一个简单的 getter 函数。

    所以基本上例如在您的情况下,您可以将ng-checked 绑定到属性

    ..ng-checked="doesExist"
    

    并在需要更新时设置属性doesExist。因此,您无需每次都检查是否存在,而是在相应事件发生时显式设置相应的属性。这也使逻辑明确。

    【讨论】:

      猜你喜欢
      • 2020-08-01
      • 2014-01-16
      • 2014-09-09
      • 2023-02-25
      • 2016-04-14
      • 2015-10-12
      • 2023-03-25
      • 2013-03-18
      • 2012-02-13
      相关资源
      最近更新 更多