Ниже добавлен мой код контроллера. Я хочу получить доступ к значению $ scope.FCGId....... Как получить доступ к этой переменной?
angular.module('hotelApp.controllers')
.controller('menuCtrl', ['$scope','menu'
function($scope,'menu') {
$scope.categories = [];
$scope.FCGId = 0
$scope.items = [];
$scope.getCategories = function() {
menu.getCategories().success(function(data) {
$scope.categories = data;
$scope.FCGId = data['rows'][0].GRPCOD;
});
}
$scope.getItems = function(gropuId) {
menu.getItems(gropuId).success(function(data) {
$scope.items = data;
console.log(data);
});
}
$scope.$on('$ionicView.afterEnter', function() {
$scope.getCategories();
console.log($scope.FCGId);
$scope.getItems($scope.FCGId);
});
}
]);
From, выше код возвращает 0 вместо значения, обновленного в функции getCategories().
Что ж
Функция $ scope.getCategories предоставляет асинхронный вызов в следующем событии
$scope.$on('$ionicView.afterEnter', function() {
$scope.getCategories();
console.log($scope.FCGId);
$scope.getItems($scope.FCGId);
});
когда вы вызываете $ scope.getCategories(), этот асинхронный вызов предоставляется.
Но сценарий не ждет завершения этого вызова. И сценарий доступа к переменной $ scope.FCGId в console.log($ scope.FCGId); без инициализации, поскольку асинхронный cal не завершен.
Решение этого.
Либо вы вызываете функцию $ scope.getCategories в начале контроллера как часть инициализации, либо вы должны возвращать обещание из функции $ scope.getCategories или использовать обещание другим способом в соответствии с вашим требованием.
ИЗМЕНИТЬ КОД.
Определены $ scope.getCategories следующим образом
inejct $ q в вашем контроллере.
var defer = $q.defer();
$scope.getCategories = function() {
menu.getCategories().success(function(data) {
$scope.categories = data;
// $scope.FCGId = data['rows'][0].GRPCOD;
defer.resolve(data['rows'][0].GRPCOD);
return defer.promise;
});
}
и обработки событий таким образом
$scope.$on('$ionicView.afterEnter', function() {
$scope.getCategories().then(function(successData){
$scope.FCGId = successData
console.log($scope.FCGId);
});
$scope.getItems($scope.FCGId);
});
Решение -2. Кроме того, нет никакой зависимости при вызове функции $ scope.getCategories, чтобы вы могли вызвать ее при запуске контролера.
То же самое можно сделать для вызова $ scope.getItems.
Ваша проблема возникает из-за того, что javascript почти всегда работает быстрее, чем возвращает асинхронный вызов, поэтому ваши $scope.getItems
всегда вызывают до $scope.getCategories
возвращается значение $scope.getCategories
.
Чтобы строго заказать вызовы API, вам нужна мощная конструкция, называемая обещанием. Там должно быть много ресурсов, просто google "угловатое обещание", и вы хороши =)
Изменить: Фактически использование функции успеха - это самый прямой способ сделать это
$scope.getCategories = function() {
menu.getCategories().success(function(data) {
$scope.categories = data;
$scope.FCGId = data['rows'][0].GRPCOD;
$scope.getItems($scope.FCGId); // to here
});
}
$scope.getItems = function(gropuId) {
menu.getItems(gropuId).success(function(data) {
$scope.items = data;
console.log(data);
});
}
$scope.$on('$ionicView.afterEnter', function() {
$scope.getCategories();
console.log($scope.FCGId);
// $scope.getItems($scope.FCGId); // move this line
});
Таким образом, вам не придется иметь дело со всеми этими $ q и d's. И обещание-антипаттерны.
Кажется, что ваш menu.getCategories() является асинхронным исполнительным блоком, и из-за отложенного выполнения вы получаете 0 в качестве значения $ scope.FCGId.
Вы можете передать функцию в качестве второго параметра функции getCategories, которая будет выполнена и выполнить необходимые назначения и дальнейшие вызовы.
$scope.setFCGValue = function(data) {
$scope.categories = data;
$scope.FCGId = data['rows'][0].GRPCOD;
$scope.getItems($scope.FCGId);
};
$scope.$on('$ionicView.afterEnter', function() {
menu.getCategories().success($scope.FCGValue);
});
Что мы делаем, это передать нашу пользовательскую функцию, которая будет выполнена после части getCategories().