为了账号安全,请及时绑定邮箱和手机立即绑定

AngularJS:在调用$Scope.$Apply()时防止已经在进行的错误$摘要

AngularJS:在调用$Scope.$Apply()时防止已经在进行的错误$摘要

慕虎7371278 2019-06-06 15:38:08
AngularJS:在调用$Scope.$Apply()时防止已经在进行的错误$摘要我发现我需要手动更新我的页面到我的范围越来越多,因为构建一个应用程序的角度。我知道的唯一办法就是打电话$apply()我的控制器和指令的范围。这样做的问题是,它不断向控制台抛出一个错误,该控制台读取:错误:美元摘要已经在进行中有没有人知道如何避免这一错误,或者以不同的方式实现相同的目标?
查看完整描述

3 回答

?
慕姐8265434

TA贡献1813条经验 获得超2个赞

不要使用这种模式-这将导致的错误多于解决的错误。即使你认为它能解决一些问题,它却没有。

您可以检查$digest已经在通过检查$scope.$$phase.

if(!$scope.$$phase) {
  //$digest or $apply}

$scope.$$phase会回来"$digest""$apply"如果$digest$apply正在进行中。我相信这些州之间的区别在于$digest将处理当前范围的表及其子表,以及$apply将处理所有范围的观察者。

@dnc 253的观点,如果你发现自己在打电话$digest$apply经常,你可能做错了。当需要更新范围的状态时,我通常会发现需要消化,因为DOM事件是在角范围之外触发的。例如,当Twitter引导模式被隐藏时。有时,DOM事件会在$digest正在进行中,有时没有。所以我才用这张支票。

如果有人知道的话,我很想知道更好的方法。


来自评论:by@anddoutoi

angular.js反模式

  1. 别这样

    if (!$scope.$$phase) $scope.$apply()

    ,这意味着

    $scope.$apply()

    在呼叫堆栈中不够高。


查看完整回答
反对 回复 2019-06-06
?
开心每一天1111

TA贡献1836条经验 获得超13个赞

最近一次与角质人的讨论就是关于这个话题的:由于将来的防伪原因,您不应该使用$$phase

当按下“正确”的方法来做这件事时,答案是当前的。

$timeout(function() {
  // anything you want can go here and will safely be run on the next digest.})

最近,我在编写棱角服务来包装Facebook、Google和TwitterAPI时遇到了这种情况,这些API在不同程度上都有回调。

下面是服务内部的一个示例。(为了简洁起见,服务的其余部分-设置变量、注入$timeout等等)。-已经停止了。)

window.gapi.client.load('oauth2', 'v2', function() {
    var request = window.gapi.client.oauth2.userinfo.get();
    request.execute(function(response) {
        // This happens outside of angular land, so wrap it in a timeout 
        // with an implied apply and blammo, we're in action.
        $timeout(function() {
            if(typeof(response['error']) !== 'undefined'){
                // If the google api sent us an error, reject the promise.
                deferred.reject(response);
            }else{
                // Resolve the promise with the whole response if ok.
                deferred.resolve(response);
            }
        });
    });});

注意,$timeout的延迟参数是可选的,如果未设置,默认为0($超时值打电话$Browser.推迟哪一个如果没有设置延迟,默认为0)

有点不直观,但这是男人写角度的答案,所以这对我来说已经足够好了!


查看完整回答
反对 回复 2019-06-06
?
翻翻过去那场雪

TA贡献2065条经验 获得超13个赞

摘要周期是一个同步调用。在完成之前,它不会将控制权让给浏览器的事件循环。有几种方法可以解决这个问题。处理这一问题的最简单方法是使用内置的$timeout,第二种方法是如果使用下划线或存档(应该是这样),则调用以下命令:

$timeout(function(){
    //any code in here will automatically have an apply run afterwards});

或者如果你有房客:

_.defer(function(){$scope.$apply();});

我们尝试了几种解决方法,我们讨厌将$rootScope注入到所有控制器、指令甚至一些工厂中。因此,到目前为止,$timeout和_.delayer一直是我们最喜欢的。这些方法成功地告诉角直到下一个动画循环,这将保证当前范围。$Apply已经结束。


查看完整回答
反对 回复 2019-06-06
  • 3 回答
  • 0 关注
  • 1467 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信