简体   繁体   English

AngularJS在控制器之间共享异步数据

[英]AngularJS sharing async data between controllers

There's quite a few topics out there covering issues with sharing data between controllers, but I havn't found any good answers for my case. 有很多话题涉及控制器之间共享数据的问题,但是我没有找到适合我的案例的好答案。

I have one controller that fetches data asynchronous using promise. 我有一个控制器,可以使用promise异步获取数据。 The controller then makes a copy of the data to work with within that scope. 然后,控制器将复制数据以在该范围内使用。 I then have a second controller which I want also want to work on the same copy of data that of the first controller so they both share it. 然后,我有第二个控制器,我也想与第一个控制器使用相同的数据副本,以便他们都共享它。

Here's some code simplified to serve as example: 这是一些简化为示例的代码:

.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;
    }
});

As the getData is async will the setCurrentData be triggered after the getCurrentData, so getCurrentData gives a different object and does not change to the correct one. 由于getData是异步的,因此setCurrentData将在getCurrentData之后触发,因此getCurrentData提供了一个不同的对象,并且不会更改为正确的对象。 I know you can solve this with broadcast and watch, but I'm trying to avoid using it if possible. 我知道您可以通过广播和观看来解决此问题,但如果可能,我会尽量避免使用它。

Refactor your factory to check if the _currentData variable has already been set - then you can simply use callbacks: 重构您的工厂以检查_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;
    }
    */
});

Now, calling your getData service will check if the data is already got and stored, if so, use that, else go get it! 现在,调用getData服务将检查是否已经获取并存储了数据,如果已存储,请使用它,否则继续获取它!

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

I would solve in this way: 我会这样解决:

.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(); 
        });
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM