AngularJS обменивается асинхронными служебными данными между контроллерами

Я знаю, что эта проблема несколько раз задавалась в stackoverflow, но я не смог найти правильного ответа.

Чего мне нужно добиться, так это иметь возможность инициировать некоторый асинхронный вызов в одном контроллере, а когда результат возвращается, обновить $scope в каком-то другом контроллере.

Я понимаю, что мне следует использовать общую службу, которая на самом деле делает вещи $http, но я не могу обновить область действия другого контроллера.

Вот мой код:

Просмотреть

<div class="screens" ng-controller="framesController">
   <div class="scroller scroll-pane" frames-scroll-pane>
         <div class="overview"> 
              {{frames}}                      
         </div>
   </div>
</div>

Сервис

 angular.module('BrightspotApp.models', []).
    factory('framesModel', function($http,globals){
       var api_path = 'clickard/GetClickardById/'; 
       var sharedService = {};

       sharedService.getAsync = function (id) { 
            sharedService.frames = {};

            $http.get(globals.serverUrl + api_path + id).
                success(function (data, status, headers, config) {
                    sharedService.frames = data;

                }).error(function (data, status, headers, config) {
                    console.log('HTTP error');
                });

        };

        return sharedService;

      });

Контроллеры

angular.module('BrightspotApp.controllers', []).

/**
* Top menu controller
*/
controller('menuController', function($scope,framesModel){
    $scope.clicked = false;
    $scope.toggle = function (item) {       
        $scope.clicked = !$scope.clicked;
        if ($scope.clicked){
               framesModel.getAsync(1);
        }
    };

    $scope.itemClass = function(item) {
        return $scope.clicked ? 'active' : undefined;
    };
}).
/**
 * Frames controller
 */ 
controller('framesController', function($scope,framesModel){

    $scope.data = [];
    $scope.frames = framesModel;
    });

Эта вещь работает в том смысле, что она фактически обновляет $scope и, следовательно, DOM, когда возвращается асинхронный вызов.

Но что мне нужно добиться, так это получить обратный вызов, когда асинхронная обработка завершится (возможно, с помощью $broadcast), чтобы уведомить контроллер фреймов, а затем получить контроль над возвращаемыми данными, чтобы я мог манипулировать ими перед обновлением $scope и, следовательно, ДОМ.

Помощь будет высоко оценена.


person Gregra    schedule 08.08.2013    source источник
comment
Используйте then вместо успеха.   -  person AlwaysALearner    schedule 08.08.2013
comment
Есть ли причина, по которой вы не можете манипулировать возвращаемыми данными внутри Success()? Затем вы можете либо присвоить обработанные данные frames, либо присвоить их какому-то другому свойству (например, manipulatedFrames), которое будет использовать frameworkController.   -  person Mark Rajcok    schedule 08.08.2013
comment
Причина в том, что я хочу применить стиль Model-View-Controller в своем коде, чтобы иметь возможность вызывать различные методы внутри моей модели фреймов. Итак, например, я хотел бы создать экземпляр фрейма из одного контроллера и получить данные внутри другого контроллера. Я также хотел бы иметь возможность манипулировать им в другом контроллере, прежде чем применять его к $scope   -  person Gregra    schedule 08.08.2013


Ответы (1)


Что-то вроде этого:

$http.get(globals.serverUrl + api_path + id).then(function(result){
    sharedService.frames = result.data;
});

Если вы хотите, чтобы ваш метод getAsync возвращал данные после завершения вызова, вы можете использовать defer:

sharedService.getAsync = function (id) { 
    sharedService.frames = {};
    var defer = $q.defer();
    $http.get(globals.serverUrl + api_path + id).
    then(function(result){
        sharedService.frames = result.data;
        defer.resolve(result.data);
    }).error(function (data, status, headers, config) {
        console.log('HTTP error');
    });
    return defer.promise;
};
person AlwaysALearner    schedule 08.08.2013
comment
Вы также можете использовать прослушиватель событий из контроллера, который не вызывает вызов службы, чтобы подписаться на значение возвращаемого результата. - person Dan Kanze; 08.08.2013
comment
$http уже возвращает промис, поэтому вам не нужно создавать новый отложенный. - person Kevin Stone; 17.10.2013