У меня есть угловой модуль, называемый сервисом.
В принципе, мне нужно вызвать функцию из другого контроллера и получить массив, который он вернет.
Поэтому я создал для этого сервис. Я вызываю функцию ControllerTwo
внутри ControllerOne
и эта функция помещает данные в служебную переменную serviceTwolist
. После этого я получаю доступ к этой переменной в ControllerTwo
.
Но моя переменная allData
которая должна быть возвратом вызова функции getListTwo()
является "undefined".
Может кто-нибудь объяснить, что случилось?
var service = angular.module('service', ['datatables']);
service.service('serviceTwo', function () {
this.serviceTwolist = [];
this.returnList = function () {
return serviceTwolist;
}
});
service.controller('ControllerOne', ['$http', '$scope', '$stateParams', '$rootScope',
'serviceTwo', function ($http, $scope, $stateParams, serviceTwo) {
$scope.crossData = function () {
$scope.$emit('getListTwo');
var allData = serviceTwo.serviceTwolist;
.....
}};
service.controller('ControllerTwo', ['$http', '$scope', '$stateParams', 'serviceTwo',
function ($http, $scope, $stateParams, serviceTwo) {
$scope.$on('getListTwo', function () {
$http.get(*******).then(
function success(response) {
serviceTwo.serviceTwolist = response.data;
},
function error(data) {
console.log(data);
window.alert(data.data.message);
}
);
});
попытка обещания # 1 Ошибка
$scope.crossData = function () {
var promise = new Promise(function (resolve, reject) {
$scope.$emit('getListTwo');
});
var allData = [];
promise.then(function (result) {
allData = serviceTwo.serviceTwolist;
}, function (err) {
console.log(err);
});
....
попытка обещания № 2 (через Андрея Драготониу) Сбой
$scope.crossData = function () {
this.promiseMethod = function () {
var deferred = $scope.$emit('getListTwo');
data = serviceTwo.serviceTwolist;
deferred.resolve(data);
return deferred.promise();
};
promiseMethod().then(function (someData) {
allData = servicetwo.serviceTwolist;
});
....
Я сделал что-то неправильно, не так ли?
http-вызов isync, после того, как controllertwo получает событие getListTwo и запускает http-запрос, он не ждет успеха http-вызова. Вы должны дождаться завершения вызова для обновления allData.
Итак, глядя на то, что у вас есть, я думаю, что ControllerTwo должен делать излучение, чтобы ControllerOne знал, что служба заполнена? Кроме того, ControllerOne должен вызывать serviceTwo.returnList(), или просто избавиться от этого метода, если это не нужно.
Я запустил ваш код, немного упростил его. отлично работает для меня. Вот что я сделал:
js:
(function () {
var service = angular.module('service', []);
service.service('serviceTwo', function () {
this.serviceTwolist = [];
this.returnList = function () {
return serviceTwolist;
}
});
service.controller('ControllerOne', ['$scope', '$rootScope',
'serviceTwo', function ($scope, serviceTwo) {
$scope.crossData = function () {
$scope.$emit('getListTwo');
var allData = serviceTwo.serviceTwolist;
}
$scope.$on('getListTwo', function () {
serviceTwo.serviceTwolist = { data: 1 };
});
}]);
})();
все, что вам нужно сделать в вашем html, - это запустить метод crossData.
Я собрал простой html, чтобы показать, что работа:
<body ng-app="service" ng-controller="ControllerOne">
<button ng-click="crossData();">Go</button>
</body>
</html>
срабатывает для меня.
Теперь, если вам нужно дождаться вызова службы, чтобы вернуть данные, а затем сделать что-то, то да использовать обещание, как предлагали другие. Вот пример обещания:
this.promiseMethod = function () {
var deferred = $.Deferred(),
data = some service call
deferred.resolve(data);
return deferred.promise();
};
Чтобы использовать его, вы затем делаете что-то вроде:
promiseMethod().then(function (someData) {
do something here
});
$scope.$emit('getListTwo')
назначитserviceTwo.serviceTwolist
синхронно, а это не так. Для этого и есть обещания.