3

我只是想在我的应用程序启动时加载数据。但是,视图加载速度比 http 请求快(当然)。一旦我的数据被正确加载,我想刷新我的视图,因为该数据定义了我的视图。

我在工厂内部尝试了 $rootScope.apply,我在其中执行 http 请求,我还尝试使用 $scope.apply 再次在控制器中直接执行 http 请求,但都没有工作,因为他们都给了我“$digest已经在进行中”

知道如何设置我的代码以使我的视图在数据加载时刷新吗?我将有几个不同的 http 请求,我想知道如何正确设置它们!我真的很感激任何意见!

这是我正在使用的一些代码。

app.factory('HttpRequestFactory', function($http, $q) {
  var HttpRequestFactory = {
    async: function(url, params) {
      var deferred = $q.defer();
      $http({
        url: url,
        method: post,
        params: params
      })
        .success(function(data, status, headers, config) {
          deferred.resolve(data);
        })
        .error(function(data, status, headers, config) {
          deferred.reject("An error occurred");
        });
      return deferred.promise;
    }
  };
  return HttpRequestFactory;
});

工厂

function initializeAll(){   
    HttpRequestFactory.async('../api', {action: 'getall'}).then(function(data) {
            //$rootScope.$apply(function () {
                allData = data;
            //});
        angular.forEach(allData, function(value, index){
            console.log('Voala!');
        });
    });
}

控制器调用工厂的函数 initializeAll()

app.controller("MainController", ["$scope", "$rootScope","MyFactory", 
    function($scope, $rootScope, MyFactory){
        MyFactory.initializeAll();
    
    }
]);
4

2 回答 2

3

天啊 !

你得到了 AngularJS 的 f* *问题!

实际上,您必须像这样执行“safeApply”,例如:

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

在 AngularJS 中,你只能同时拥有一个 $apply 或 $digest 循环。

有关这些循环的详细信息,请查看文档: http ://docs.angularjs.org/guide/concepts

它将解释什么是 $apply 循环,并且您将了解很多关于 AngularJS 中的双向数据绑定的事情

希望能帮助到你。

于 2013-09-17T12:26:06.190 回答
3

不要使用$apply:使用$watch

打电话$apply(几乎)总是做错事。唯一一次你应该调用它是如果你触发了一个“角度”方法之外的变化;在这里,由于触发器发生在角度$http请求中,因此您无法调用$apply,因为此时$http块已经完成了它。相反,您想要做的是$watch.

$scope.$watch() 的官方文档在这里

这将让您观察对象并在其更改时进行更新。我假设您的观点基于allData并且您希望它立即更新;如果您使用的是一种ng方法,那么手表会自动为您设置好,无需再进行任何工作。如果您在allData控制器中使用自己,则可以在该控制器中编写手表,如下所示:

$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.
      }
);
于 2013-12-30T21:32:18.857 回答