AngularJS,我如何使用服务来捕获HTTP数据并将其绑定到我的控制器
AngularJS, how do I use a service to capture HTTP data and bind it to my controller?
我有一个API调用,它工作得很好,但我想在几个控制器上使用它,所以我把它移到了它自己的服务中。我遇到了一个经典的Scope问题,或者对Angular的摘要周期的误解。
'use strict';
myApp.factory('Stuff',['$http', function ($http) {
var Stuff = {};
Stuff.data = {};
Stuff.api = 'http://localhost:8080/api/';
Stuff.getStuff = function() {
var http_stuff_config = {
method: 'GET',
url: Stuff.api + 'stuff/'
};
$http(http_stuff_config).then(function successCallback(response) {
Stuff.data = (response.data);
console.log(Stuff.data); // Returns populated object.
},function errorCallback(response) {
console.log(response.statusText);
});
};
Stuff.getStuff();
console.log(Stuff.data); // Returns empty object.
return Stuff;
}]);
myApp.controller('appController', ['$scope','Stuff',function($scope,Stuff) {
$scope.stuff = Stuff;
console.log($scope.stuff.data); // Returns empty object.
$scope.stuff.getJobs();
console.log($scope.stuff.data); // Returns empty object.
}]);
这是一条重要的线索。上面的基本输出,按顺序是…
- 空对象(在调用方法后处于服务中)
- 空对象(在调用方法之前在控制器中)
- 空对象(调用方法后在控制器中)
- 填充的对象(在从服务执行方法时)
- 填充的对象(在从控制器执行方法时)
因此,在getStuff()方法的范围和Angular的操作顺序之间,我正在做一些非常愚蠢的事情。提前谢谢。
您需要在服务上添加退货,否则承诺将不会返回到控制器。只将返回结果存储在服务中而不将结果返回到控制器是不好的做法。
这被认为是一种糟糕的做法,因为每当您更新服务上的数据时,每个人都需要将$scope.$watch
应用于服务以查找更新。这在大型应用程序中可能非常昂贵。
最好的想法是将数据返回给调用控制器(如果您不需要缓存数据,我们稍后会讨论),并让控制器通过promise service.getthing().then(function(result){});
访问数据
myApp.factory('Stuff',['$http', function ($http) {
var Stuff = {};
Stuff.data = {};
Stuff.api = 'http://localhost:8080/api/';
Stuff.getStuff = function() {
var http_stuff_config = {
method: 'GET',
url: Stuff.api + 'stuff/'
};
return $http(http_stuff_config).then(function successCallback(response) {
return response.data;
console.log(Stuff.data); // Returns populated object.
},function errorCallback(response) {
console.log(response.statusText);
});
};
Stuff.getStuff();
console.log(Stuff.data); // Returns empty object.
return Stuff;
}]);
myApp.controller('appController', ['$scope','Stuff',function($scope,Stuff) {
$scope.stuff = Stuff;
console.log($scope.stuff.data); // Returns empty object.
$scope.stuff.getJobs().then(function(result) {$scope.stuff = result; console.log(result);});
console.log($scope.stuff.data); // Returns empty object.
}]);
我建议您不要将结果存储在服务本身(Stuff.data)中。只需在getStuff函数中返回数据,并让appController的作用域存储数据即可。
$scope.stuff.getJobs()
是异步
(这意味着你实际上无法在下一行调用console.log($scope.stuff.data)
并获取数据)
现在,如果您有一个视图,使用类似<span ng-bind="stuff.data.property">
的东西,您可以看到它工作得很好,因为当异步函数完成时,视图会自行更新。(这是角度的一部分)
您需要了解,当您运行$http时,它正在发出AJAX请求。因此它不会立即返回结果。
因此,如果您尝试使用来自$scope.stuff.getJobs();调用此函数后,您可能会立即一无所获。
您应该做的是让Stuff.getJobs()返回一个promise,并使用promise.then(您自己的成功处理程序)正确处理返回的响应。
我已经稍微清理了一下你的代码。以下是从Yahoo Weather API检索数据的代码的运行示例。
你可以在CODEPEN上玩它。
html:
<div ng-app="myApp" ng-controller="appController">
<p>{{data}}</p>
</div>
JS:
var myApp = angular.module("myApp", []);
myApp.factory('Stuff',['$http', function ($http) {
var Stuff = {};
Stuff.data = {};
//sample yahoo weather api
Stuff.api = 'https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3D%22nome%2C%20ak%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys';
Stuff.getData = function() {
var http_stuff_config = {
method: 'GET',
url: Stuff.api + 'stuff/'
};
return $http(http_stuff_config);
};
return Stuff;
}]);
myApp.controller('appController', ['$scope','Stuff',function($scope,Stuff) {
$scope.data = "$http service not ran";
var uncompletedAjaxCall = Stuff.getData();
uncompletedAjaxCall.then(
function(responseData){
$scope.data = responseData;
},
function(errorMsg){}
);
}]);
- 在VanillaJS中模拟模型双向数据绑定
- Telerik rad组合框多列数据绑定
- 数据绑定:'系统Char'不包含名为'xxxxx'
- OnsenUI AngularJS数据绑定无法正常工作
- Ionic-item在导航栏中进行双向数据绑定
- 基本D3.js:如何将具有其他属性的数据绑定到元素
- 使用自定义数据属性或将数据绑定到处理程序来处理事件
- ListView的ItemTemplate内的自定义HtmlControl的数据绑定失败
- $http中的Angular 1数据绑定承诺不起作用
- 在何处和何时添加具有数据绑定的元素
- 使用AngularJs数据绑定的三元运算符显示图像
- 为什么针对工厂的Angular数据绑定只适用于函数
- 敲除:如何使用可见数据绑定可见来隐藏段落标记
- 在数据绑定中使用对象敲除绑定
- 如何在angularjs中检查Kendo树视图数据绑定事件
- 将json数据绑定到剑道网格
- AngularJS数据绑定中断ngRepeat+奇怪行为
- JavaScript HTMLElement 属性上的数据绑定 在 Polymer 中
- 视窗 8/Metro UI 数据绑定 JavaScript
- 挖空和显示模块模式的数据绑定问题