2016-08-01 77 views
0

我對AngularJS相當陌生,剛開始掌握很多我特別喜歡MVC設計模式的概念。但是我在我的應用程序中實現服務層時很困難。角度服務與控制器同步工作

我發現的是,在我的Controller調用服務中的一個方法後,它會在服務返回數據之前繼續執行代碼;這樣在服務返回數據時,它對控制器沒有任何用處。

爲了讓我在說什麼的一個更好的例子,這裏是代碼:

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世界中,我將服務移動到Controller內部以確保它執行異步;但我不知道如何在Angular中實現這一點。而且,無論如何,反角度注入都是不利的。

那麼這樣做的正確方法是什麼?

+0

大家都說返回一個承諾! Angular 2整合了RxJS(Reactive Extensions)。Angular 1你必須自己做,但想法是一樣的。這是你必須學習的'Observer' =>'Observable'模式。 –

回答

1

http返回一個承諾而不是數據,所以在你的工廠你返回$ http的承諾,並可以像使用承諾那樣使用它,catch,finally方法。

看到: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 
    }); 

EDIT通PARAMS建模服務:

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

謝謝!這正是我所期待的。它工作的服務和控制器工作異步和響應實際上提供了預期的數據。 – Mark

+0

我知道這不是我的問題的最初部分,只是延伸了一點答案;如何使用此模型將參數傳遞給相同的服務? – Mark

+0

我剛更新了我的帖子 – Gatsbill

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狀態代碼。它不包含數據。有任何想法嗎? – Mark

+0

您必須使用'response.data'獲取數據 –

0

你應該這樣進行:

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

其實$ http.get返回一個Promise。你可以調用方法來處理你的Promise的成功或失敗

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 
});