我继承了一个角度应用程序,现在需要进行更改。
作为此更改的一部分,需要在一个控制器中设置一些数据,然后从另一个控制器中使用。所以我创建了一个服务,让一个控制器将数据写入其中,一个控制器从中读取数据。
angular.module('appRoot.controllers')
.controller('pageController', function (myApiService, myService) {
// load data from API call
var data = myApiService.getData();
// Write data into service
myService.addData(data);
})
.controller('pageSubController', function (myService) {
// Read data from service
var data = myService.getData();
// Do something with data....
})
但是,当我在data
中使用pageSubController
时,它始终未定义。
如何确保pageController
之前执行pageSubController
?或者这是否是正确的问题?
修改
我的服务代码:
angular.module('appRoot.factories')
.factory('myService', function () {
var data = [];
var addData = function (d) {
data = d;
};
var getData = function () {
return data;
};
return {
addData: addData,
getData: getData
};
})
答案 0 :(得分:6)
如果您希望控制器等待,直到另一个控制器得到响应。您可以尝试在angularjs中使用$broadcast
选项。
在页面控制器中,您必须广播您的消息“dataAdded”,并且在pagesubcontroller中您必须使用$ scope。$ on等待消息,然后处理“getData”函数。
您可以尝试这样的事情:
angular.module('appRoot.controllers')
.controller('pageController', function (myApiService, myService,$rootScope) {
// load data from API call
var data = myApiService.getData();
// Write data into service
myService.addData(data);
$rootScope.$broadcast('dataAdded', data);
})
.controller('pageSubController', function (myService,$rootScope) {
// Read data from service
$scope.$on('dataAdded', function(event, data) {
var data = myService.getData();
}
// Do something with data....
})
答案 1 :(得分:2)
我会更改您的服务以返回数据承诺。当被问及是否尚未设置数据时,只需返回承诺。稍后当另一个控制器设置数据时,使用数据解析先前的承诺。我已经使用这种模式来处理缓存API结果,使得控制器不知道或不关心我是从API获取数据还是仅返回缓存数据。类似于此的东西,尽管您可能需要保留一组待处理的promises,这些promises需要在实际设置数据时解析。
function MyService($http, $q, $timeout) {
var factory = {};
factory.get = function getItem(itemId) {
if (!itemId) {
throw new Error('itemId is required for MyService.get');
}
var deferred = $q.defer();
if (factory.item && factory.item._id === itemId) {
$timeout(function () {
deferred.resolve(factory.item);
}, 0);
} else {
$http.get('/api/items/' + itemId).then(function (resp) {
factory.item = resp.data;
deferred.resolve(factory.item);
});
}
return deferred.promise;
};
return factory;
}