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)

Другие вопросы по тегам