2014-06-05 2 views
1

У меня есть 2 контроллера (Продукты) и (ProductsFilters) и 1 сервис (ProductService).Как обменять данные AJAX между двумя контроллерами в AngularJS

2 контроллера загружаются одновременно с тем, как второй (ProductFilter) действует как боковое меню для первого контроллера (Products).

Контроллер продуктов вызывает службу AJAX через ProductService и назначает возвращаемые данные переменной (Facets) в ProductService.

В то же время ProductFilter извлекает (Facets) из ProductService.

Проблема: теперь я хочу обработать некоторые данные в контроллере ProductFilter до того, как он будет отображаться в представлении, но во время выполнения ProductService.Facets возвращают пустой объект, потому что вызов AJAX не был завершен все же!

Я попробовал $ watch() ProductService.Facets, но это не сработало.

Вот сервисный продукт

.factory('ProductService', function(AppService, CategoryService, $stateParams, $location, $http) { 
return { 
facets: {}, 
browse: function(category_id, page, order, order_type) { 

    url = AppService.apiUrl() + 'products/browse.json?' + params; 

    var that = this; 

    return this.getProducts(url).then(function(response) { 
    that.facets.grouped_brands = response.grouped_brands; 
    that.facets.grouped_categories = response.grouped_categories; 
    that.facets.grouped_prices = response.grouped_prices; 
    that.facets.grouped_stores = response.grouped_stores; 

    return response; 
    }); 

}, 
getProducts: function(url) { 
    return $http.jsonp(url + '&callback=JSON_CALLBACK&ref=mobile_app', {cache: true}) 
    .then(function(response) { 
     if (typeof response.data === 'object') { 
     return response.data; 
     } 
    }); 
    } 
    } 
}) 

Вот контроллер Продукты:

.controller('ProductsController', function($scope, ProductService) { 

    $scope.page = 1; 

    $scope.moreProducts = function() { 
    ProductService.browse(180, $scope.page) 
     .then(function(products) { 
     angular.extend($scope.products, products.products); 
     $scope.page +=1; 
     } 
    ); 
    } 

    $scope.products = {} 

}) 

А вот контроллер ProductsFilter:

.controller('ProductsFiltersController', function($scope, ProductService) { 
    $scope.facets = ProductService.facets; 
    $scope.brand_facets = [] 

    $scope.$watch('facets', function() { 
    angular.forEach($scope.facets.grouped_brands, function(value, key) { 
     $scope.brand_facets.push({brand: key, count: value}) 
    }); 
    }); 
}) 
+0

Можете ли вы уточнить, как это не сработало? Не могли бы вы также предоставить образец кода '$ watch', который вы пытались использовать? –

+0

Ваш код '$ watch '? Я бы предложил это или использовать '$ broadcast' и' $ on' в методе обратного вызова AJAX. –

+0

Можете ли вы опубликовать некоторый пример кода по крайней мере на вашей логике 'Productervice' – guru

ответ

1

Вы можете использовать углы $broadcast и $on, чтобы сообщить второму контроллеру, когда получен ответ ajax.

Как точно реализовать функцию широковещания зависит от соотношения между вашими контроллерами. Вы можете использовать этот SO-ответ в качестве справки: $scope.$emit and .$on angularJS

+0

Я пробовал $ rootScope. $ Broadcast, но это не сработало! –

+1

Я использовал $ rootScope. $ Emit() в службе и $ rootScope.on() на контроллере, и он работал нормально. –

0

Похоже, у вас есть асинхронный ошибка в вашем сервисе. Вам либо нужно, чтобы обратный вызов запроса AJAX возвращал данные контроллерам, либо использовал $ q для создания обещания, которое возвращается контроллерам.

https://docs.angularjs.org/api/ng/service/ $ д

$ д позволяет создать отложенный объект. Поэтому вместо службы, возвращающей нулевой объект, он вернет обещание, что ваш контроллер сможет действовать, как только он будет выполнен.

+1

Я думаю, что проблема с этим подходом заключается в том, что один контроллер вызывает метод службы, но другой контроллер не будет знать об этом, не будучи уведомленным каким-то образом, поэтому вам потребуется отложить с какой-то сигнализацией типа '$ watch'. Кроме того, если предположить, что это можно было бы назвать несколько раз, вам нужно будет создать и обработать несколько отложенных, поскольку каждый из них обрабатывает только одно решение. –

Смежные вопросы