3

嘿傢伙,所以我只是試圖在我的應用程序啓動時加載數據。但是,視圖的加載速度比http請求快(當然)。一旦我的數據正確加載,我想刷新我的視圖,因爲這些數據定義了我的視圖。

我試過$ rootScope.apply從工廠,我做我的http請求裏面,我也試過直接與$老毛病又犯在我的控制器的http請求scope.apply,並沒有一個合作,他們倆給我「$摘要已在進行中」

任何想法如何設置我的代碼,使我的視圖刷新數據加載?我將有幾個不同的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(); 

    } 
]); 
+0

您可以創建一個的jsfiddle?我真的懷疑你的代碼是否工作。至少我可以看到一些語法錯誤。 'method:post,'將會破壞你的代碼,因爲'post'需要是一個字符串。謝謝。 – zsong

+0

hey sza,post實際上是一個在文件中聲明的常量,它是如何工作的。我會盡力爭取一個jsFiddle。 –

+0

你有沒有試過不打'$ apply'? '$ http'服務的'success'回調被Angular本身調用'$ apply'。 –

回答

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你只能有一個$應用或$在同一時間消化循環。

有關這些循環的細節看文檔:在AngularJS

http://docs.angularjs.org/guide/concepts

這將解釋什麼是$應用循環,你就會明白一個關於很多東西雙向數據綁定

希望它有幫助。

3

Don't use $apply: use $watch.

調用$apply(幾乎)總是錯誤的做法。唯一一次你應該調用它是因爲你觸發了一個'角度'方法之外的變化;這裏,因爲觸發發生在角度$http請求中,所以不能調用$apply,因爲它已由$http塊執行。相反,你想要做的是$watch

Official Doc for $scope.$watch() here

這將讓你看一個對象,並更新每當它改變。我假設您的觀點基於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. 
     } 
);