AngularJS отложил обещание в запросе Jolokia
У меня есть приложение в качестве плагина в среде Hawtio. Требуется использовать запросы Jolokia вместо прямого $http
сервисные звонки.
Так что у меня есть фабрика / сервис, который имеет функцию извлечения.
app.factory('myService', function($q, jolokia) {
data: {
list: []
},
retrieve: function() {
var self = this;
// var deferred = $q.deferred();
jolokia.request({
type: 'exec',
mbean: mybean.mbean,
operation: 'ops',
arguments: [...]
}, {
method: 'POST',
success: function(response) {
var temp = [];
/* assign values to temp from response */
self.assignValuesToList(temp);
/* log shows data.list is loaded by values */
log("[service] " + self.data.list); // Hawtio uses a different logger
// deferred.resolve();
}
}, {
error: function(error) {
// error handling here
// deferred.reject(error);
}
});
// return deferred.promise;
}
});
Это мой контроллер (сервис повторно используется другими контроллерами, поэтому я должен переназначить myService.data.list
даже если myController
сфера уже контролирует его):
app.controller('myController', function($scope, myService) {
$scope.ctrl.copyOfList = [];
angular.extend($scope, myService);
$scope.init = function() {
$scope.search();
log("[after search] " + $scope.ctrl.copyOfList);
};
$scope.search = function {
$scope.retrieve();
$scope.ctrl.copyOfList = $scope.data.list;
$scope.$apply();
log("[search] " + $scope.ctrl.copyOfList);
};
});
и HTML:
<div ng-controller='myController' ng-init='init()'>
<table>
<thead>...</thead>
<tbody>
<tr ng-repeat='entry in ctrl.copyOfList'>
...
</tr>
</table>
</div>
Это последовательность моих логов:
[search] [] // empty
[after search] [] // empty
[service] [...] // service.data.list has values fetched by jolokia request from server
и стол пуст.
Из-за асинхронной проблемы я попытался использовать обещание (просто раскомментируйте отложенные строки службы выше). Мой контроллер становится
app.controller('myController', function($scope, myService) {
$scope.ctrl.copyOfList = [];
angular.extend($scope, myService);
$scope.init = function() {
$scope.search();
log("[after search] " + $scope.ctrl.copyOfList);
};
$scope.search = function {
$scope.retrieve().
then(function() {
$scope.ctrl.copyOfList = $scope.data.list;
log("[controller] " + $scope.ctrl.copyOfList);
$scope.$apply();
}, function(error) {
// error handling here
});
log("[after promise] " + $scope.ctrl.copyOfList);
};
});
И теперь мои журналы выглядят так:
[after promise] []
[after search] []
[service] [...]
// [controller] [...] log does not execute
и стол еще пуст. Что еще более запутанно здесь, прежде чем я покидаю страницу, которая использует myController
, [controller][...]
журнал напечатает на консоли и запишет содержимое $scope.ctrl.copyOfList
и мгновенно заполняет таблицу, а затем внезапно меняет страницу.
(Я также пытался использовать deferred.resolve(self.data.list)
вместо deferred.resolve()
В том числе необходимые изменения на контроллере, но это не имеет значения, тот же результат, хотя).
Так что каждый может здесь, кто может выяснить, что происходит, и что может быть решением здесь? Благодарю.
1 ответ
В обратном вызове jolokia success/error вам нужен $scope.$ Apply() для запуска цикла событий angular. В таком сервисе я обычно внедряю $rootScope и использую Core.$ Apply($rootScope)