AngularJS - refresh view after http request, $rootScope.apply returns $digest already in progress

老子叫甜甜 提交于 2019-12-06 03:30:59

Oh my !

You got the f** matter with AngularJS !

In fact you have to do a "safeApply" like that for example :

$rootScope.safeApply = function(fn) {
    var phase = this.$root.$$phase;
    if(phase == '$apply' || phase == '$digest') {
        if(fn && (typeof(fn) === 'function')) {
            fn();
        }
    } else {
        this.$apply(fn);
    }
};

In AngularJS you can only have one $apply or $digest loop at the same time.

For details on these loops look at the docs : http://docs.angularjs.org/guide/concepts

It will explain what is the $apply loop and you'll understand a lot of things about the two-way-data-binding in AngularJS

Hope it helps.

Hylianpuffball

Don't use $apply: use $watch.

Calling $apply is (almost) always the wrong thing to do. The only time you should ever be calling it is if you've triggered a change outside of an 'angular' method; here, since the trigger occurs in an angular $http request, you can't call $apply because it's already being done at that moment by the $http block. Instead, what you want to do is $watch.

Official Doc for $scope.$watch() here

This will let you watch an object and update whenever it changes. I assume that your view is based on allData and you want it to update immediately; if you're using an ng method, then the watch is automatically setup for you and no more work should be needed. If you're using allData yourself inside a controller, you can write the watch in that controller like this:

$scope.$watch(function thingYouWantToWatch(){
         return <accessor call to allData here>;
      }, 
      function whatToDoOnChange(newValue, oldValue){
          $scope.myCoolThing = newValue; //this is the newValue of allData, or whatever you're watching.
      }
);
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!