使用$ timeout来强制执行,是一种不好的做法?

时间:2017-06-30 23:30:02

标签: javascript angularjs ionic-framework

我正在使用离子3.所以我在控制器上有这个代码,它可以正常工作

$scope.note = 'Lorem...';

$rootScope.$on('Active',function() {
    $timeout(function() {
        $scope.note = 'test';
    },0);
}); 

但为什么这不起作用?

$scope.note = 'Lorem...';

$rootScope.$on('Active',function() {
    $scope.note = 'test';
}); 

最佳方法是什么?

2 个答案:

答案 0 :(得分:1)

在这种情况下,它可以被认为是一种不好的做法。自发使用$timeout通常表示开发人员不知道代码是在摘要周期内部还是外部运行,并试图将其安全地播放。

为什么这不起作用的解释不在发布代码的范围之内,但原因是此代码在摘要之外运行。这取决于触发Active范围事件的位置,这是开发人员应该首先关注的内容,因为范围事件不一定发生在摘要周期内。

如果已知事件发生在摘要之外,则依赖于摘要的代码应包含$apply

$scope.$on('Active',function() {
    $scope.$apply(function() {
        $scope.note = 'test';
    });
}); 

如果已知事件在摘要内部和外部发生,则代码应包含$evalAsync

$scope.$on('Active',function() {
    $scope.$evalAsync(function() {
        $scope.note = 'test';
    });
});

$timeout(...)应该只在需要它的行为时使用,即一个滴答延迟或更多时间和摘要。

正如@georgeawg所建议的那样,在控制器中使用$rootScope作为全局事件总线也是一种不好的做法(他们可以访问子范围)。这基本上是一个可能导致内存泄漏的反模式。考虑到事件是$broadcast,它将传播到子范围。根据经验,它应该是$scope.$on(...),除非有理由认为应该专门针对$rootScope进行。

答案 1 :(得分:0)

当视图未收到控制器更改通知时,会发生这种情况。它通常发生在ng-repeat数组/对象或不使用全局对象的表单内。 $ timeout解决方案有效,或者您可以调用$ scope。$ apply()。请查看此文档以获取更多信息:

https://www.sitepoint.com/understanding-angulars-apply-digest/