2015-01-15 70 views
1

有很多話題涉及控制器之間共享數據的問題,但我沒有找到任何好的答案。AngularJS在控制器之間共享異步數據

我有一個控制器使用promise來獲取異步數據。然後控制器會在該範圍內複製數據以使用。然後我有第二個控制器,我想也想處理與第一個控制器相同的數據副本,以便他們共享它。

下面是一些代碼的簡化,作爲例子:

.controller('firstController', function ($scope, someService){ 
    var vm = this; 
    someService.getData().then(function(data) { 
     angular.copy(data, vm.data); //creates a copy and places it on scope 
     someService.setCurrentData(vm.data) 
    } 
}); 

.controller('secondController', function ($scope, someService){ 
    var vm = this; 
    vm.data = someService.getCurrentData(); //Triggers before the setter in firstController 
}); 

.factory('someService', function(fetchService){ 
    var _currentData = {}; 

    var getData = function(){ 
     return fetchService.fetchData().then(function(data) { return data; }); 
    }; 

    var getCurrentData = function(){ 
     return _currentData; 
    } 

    var setCurrentData = function(data){ 
     _currentData = data; 
    } 
}); 

由於的getData是異步將setCurrentData的getCurrentData之後被觸發,所以getCurrentData給出了不同的對象,並不會更改爲正確的一個。我知道你可以通過廣播和觀看來解決這個問題,但我儘可能避免使用它。

+1

你應該保持對getCurrentData(異步API),如果沒有設置_currentData,getCurrentData()應調用的getData()。 – eddiec 2015-01-15 16:00:59

回答

4

重構你的工廠檢查_currentData變量已經設置 - 那麼你可以簡單地使用回調:

現在
app.factory('someService', function(fetchService){ 
    var _currentData = null; 

    var setCurrentData = function(data){ 
     _currentData = data; 
    } 

    var getData = function(callback) { 
     if (_currentData == null) { 
      fetchService.fetchData().success(function(data) { 
       setCurrentData(data); 
       callback(data); 
      }); 
     } else { 
      callback(_currentData); 
     } 
    }; 

    /* 
    var getCurrentData = function(){ 
     return _currentData; 
    } 
    */ 
}); 

,呼喚你的getData服務將檢查數據是否已經拿到並保存,如果所以,使用它,否則去得到它!

someService.getData(function(data) { 
    console.log(data); //yay for persistence! 
}) 
+0

不錯,但我不喜歡的是getData中的回調函數。 getData返回承諾會不會更好? – zszep 2015-01-15 17:10:02

2

我會解決這樣:

.controller('firstController', function ($scope, $rootScope, someService){ 
    var vm = this; 
    someService.getData().then(function(data) { 
     angular.copy(data, vm.data); //creates a copy and places it on scope 
     someService.setCurrentData(vm.data); 
     $rootScope.$broadcast('myData:updated'); 
    } 
}); 



.controller('secondController', function ($scope, $rootScope, someService){ 
     var vm = this; 
     $rootScope.$on('myData:updated', function(event, data) { 
      vm.data = someService.getCurrentData(); 
     }); 
}); 
相關問題