Angular Service работает синхронно с контроллером

0

Я новичок в AngularJS и только начал понимать многие из концепций, которые мне особенно нравятся в шаблоне проектирования MVC. Но мне сложно выполнить уровень сервиса в моем приложении.

Я нахожу, что после того, как мой контроллер вызывает метод внутри службы, он продолжает выполнение кода до того, как служба вернет данные; так что к тому времени, когда служба вернет данные, она не будет использоваться контроллером.

Чтобы дать лучший пример того, что я говорю, вот код:

var InsightApp = angular.module('InsightApp', ['chart.js']);

// Module declaration with factory containing the service
InsightApp.factory("DataService", function ($http) {
return {
    GetChartSelections: function () {
            return $http.get('Home/GetSalesData')
                .then(function (result) {
                return result.data;
            });
        }
    };
});

InsightApp.controller("ChartSelectionController", GetAvailableCharts);

// 2nd Controller calls the Service
InsightApp.controller("DataController", function($scope, $http, DataService){
var response = DataService.GetChartSelections();

// This method is executed before the service returns the data 
function workWithData(response){
    // Do Something with Data
   }
}

Все примеры, которые я нашел, по-видимому, сконструированы так, как я здесь, или некоторые незначительные вариации; поэтому я не уверен, что я должен делать, чтобы обеспечить асинхронное выполнение.

В мире Javascript я переместил службу внутрь контроллера, чтобы убедиться, что он выполняет асинхронный вызов; но я не знаю, как это произошло в Angular. Кроме того, в любом случае это было бы противодействовать интуиции против угловой инъекции.

Итак, каков правильный способ сделать это?

  • 0
    Все говорят, верни обещание! Angular 2 включает в себя RxJS (Reactive Extensions). Angular 1 вы должны сделать это сами, но идея та же. Это шаблон Observer => Observable , который вы должны изучить.
Теги:
model-view-controller

4 ответа

1
Лучший ответ

http возвратите обещание не данные, поэтому на вашем заводе вы возвращаете $ http обещают и можете использовать его, как обещание, а затем, поймать, наконец-то метод.

см.: http://blog.ninja-squad.com/2015/05/28/angularjs-promises/

InsightApp.controller("DataController", function($scope, $http, DataService){

var response = DataService.GetChartSelections()
    .then(function(res) {
       // execute when you have the data
    })
    .catch(function(err) {
      // execute if you have an error in your http call
    });

Изменить параметры доступа к службе модели:

InsightApp.factory("DataService", function ($http) {
return {
    GetChartSelections: function (yourParameter) {
            console.log(yourParameter);
            return $http.get('Home/GetSalesData')
                .then(function (result) {
                return result.data;
            });
        }
    };
});

а потом:

InsightApp.controller("DataController", function($scope, $http, DataService){

var response = DataService.GetChartSelections('only pie one')
    .then(function(res) {
       // execute when you have the data
    })
    .catch(function(err) {
      // execute if you have an error in your http call
    });
  • 0
    Спасибо! Это именно то, что я искал. Работает служба, а контроллер работает асинхронно, а ответ фактически предоставляет данные, как и ожидалось.
  • 0
    Я знаю, что это была не начальная часть моего вопроса, а лишь небольшая часть вашего ответа; Как передать параметр в тот же сервис, используя эту модель?
Показать ещё 2 комментария
0

Если это не так, когда ваш $ http возвращает обещание или вы передаете обратный вызов.

С передачей callback в качестве param.

InsightApp.factory("DataService", function ($http) {
return {
    GetChartSelections: function (workWithData) {
            return $http.get('Home/GetSalesData')
                .then(function (result) {
                workWithData(result.data);
            });
        }
    };
});

Код контроллера:

InsightApp.controller("DataController", function($scope, $http, DataService){
var response = DataService.GetChartSelections(workWithData);

// This method is executed before the service returns the data 
function workWithData(response){
    // Do Something with Data
   }
}

Или используйте то или успех:

var response = DataService.GetChartSelections().then(function(res){
      //you have your response here... which you can pass to workWithData
});
0

Вы должны действовать следующим образом:

DataService.GetChartSelections().then(function (data) {
     workWithData(data);
}

На самом деле $ http.get возвращает Promise. Вы можете вызвать метод, чтобы справиться с успехом или неудачей вашего обещания

0

Верните обещание к контроллеру, не разрешите его на заводе

    var InsightApp = angular.module('InsightApp', ['chart.js']);

    // Module declaration with factory containing the service
    InsightApp.factory("DataService", function ($http) {
    return {
        GetChartSelections: function () {
                return $http.get('Home/GetSalesData');
            }
        };
    });

В контроллере,

var successCallBk =function (response){
    // Do Something with Data
};
var errorCallBK =function (response){
    // Error Module
};

var response = DataService.GetChartSelections().then(successCallBk,errorCallBK);
  • 0
    Ваш пример кода, кажется, обеспечивает асинхронное выполнение, но ответом является код состояния http OK. Он не содержит данных. Есть идеи?
  • 0
    Вы должны использовать response.data для получения данных

Ещё вопросы

Сообщество Overcoder
Наверх
Меню