Javascript 在AngularJS中使用工厂和http
我刚刚开始学习angular,并且看到可以定义一个工厂用于多个控制器 我有下面的代码,它在“success”方法中返回我的结果。但不是在功能之外 我觉得这与异步有关,但如果是这样的话,我不太确定如何继续 如有任何帮助,我们将不胜感激,敬请提前感谢Javascript 在AngularJS中使用工厂和http,javascript,angularjs,http,factory,Javascript,Angularjs,Http,Factory,我刚刚开始学习angular,并且看到可以定义一个工厂用于多个控制器 我有下面的代码,它在“success”方法中返回我的结果。但不是在功能之外 我觉得这与异步有关,但如果是这样的话,我不太确定如何继续 如有任何帮助,我们将不胜感激,敬请提前感谢 var abyssApp = angular.module('abyssApp', []); abyssApp.factory('abyssData', function($http) { var result, produc
var abyssApp = angular.module('abyssApp', []);
abyssApp.factory('abyssData', function($http) {
var result,
products = $http.get('http://abyss.local/products.php');
products.success(function(data) {
result = angular.fromJson(data);
console.log('success: ', result); // object with data in
});
console.log(result); // undefined
});
abyssApp.controller('ItemListCtrl', function($scope, abyssData) {
$scope.items = abyssData;
console.log('abyssData: ', abyssData); // undefined
});
在“ItemListCtrl”中,应该注入从“AbysData”工厂创建的对象。然后,它应该返回$http PROMITE,并直接在控制器中,在成功回调中,您应该将返回的结果分配给$scope.items。这只是一种示例方法,有很多方法和模式可以帮助您解决这些问题
console.log(result); // undefined
记录“未定义”,因为当您调用此行时,还没有响应。试着弄清楚什么是承诺以及AJAX调用是如何工作的,特别是应该定义什么“成功”和“错误”。在“ItemListCtrl”中,您应该注入从“AbysData”工厂创建的对象。然后,它应该返回$http PROMITE,并直接在控制器中,在成功回调中,您应该将返回的结果分配给$scope.items。这只是一种示例方法,有很多方法和模式可以帮助您解决这些问题
console.log(result); // undefined
记录“未定义”,因为当您调用此行时,还没有响应。试着弄清楚什么是承诺,AJAX调用到底是如何工作的,特别是应该定义什么“成功”和“错误”。反过来说。首先,工厂应该返回一个值。该值是一个单例。这意味着在工厂被执行之后,它不会执行自己超过一次。您可以做的是返回一个引用您的结果的对象
abyssApp.factory('abyssData', function($http) {
var ret = {},
products = $http.get('http://abyss.local/products.php')
products.success(function(data) {
ret.result = angular.fromJson(data);
console.log('success: ', result); // object with data in
});
console.log(result); // undefined
return ret;
});
abyssApp.controller('ItemListCtrl', function($scope, abyssData) {
$scope.items = abyssData.result;
console.log('abyssData: ', abyssData); // undefined
});
但是这个解决方案闻起来不是很好。除非您的对象列表永远不会更新。返回在需要时可以查询的资源更有意义。不确定控制器何时加载,结果是否已经加载。这意味着访问AbysData.result可能首先返回未定义的undefined
,然后返回其他内容
但老实说,你要做的应该是:
$resource
你可以有一个这样的工厂:
abyssApp.factory('AbyssData', ['$resource', function($resource) {
return $resource('http://abyss.local/products.php')
}])
abyssApp.factory('abyssData', ['AbyssData', function(AbyssData) {
return AbyssData.query();
}])
var abyssApp = angular.module('abyssApp', []);
abyssApp.factory('abyssData', function($http) {
function abyssData() {
var self = this;
self.products = null;
self.getProducts = function(){
// return products if they are set already (cache)
if (self.products) { return self.products; }
$http.get('http://abyss.local/products.php').success(function(data){
self.products = data;
return self.products;
});
};
}
return new abyssData();
});
abyssApp.controller('ItemListCtrl', function($scope, abyssData) {
$scope.items = abyssData.getProducts();
});
看看这个:$resource你有它的另一种方式。首先,工厂应该返回一个值。该值是一个单例。这意味着在工厂被执行之后,它不会执行自己超过一次。您可以做的是返回一个引用您的结果的对象
abyssApp.factory('abyssData', function($http) {
var ret = {},
products = $http.get('http://abyss.local/products.php')
products.success(function(data) {
ret.result = angular.fromJson(data);
console.log('success: ', result); // object with data in
});
console.log(result); // undefined
return ret;
});
abyssApp.controller('ItemListCtrl', function($scope, abyssData) {
$scope.items = abyssData.result;
console.log('abyssData: ', abyssData); // undefined
});
但是这个解决方案闻起来不是很好。除非您的对象列表永远不会更新。返回在需要时可以查询的资源更有意义。不确定控制器何时加载,结果是否已经加载。这意味着访问AbysData.result可能首先返回未定义的undefined
,然后返回其他内容
但老实说,你要做的应该是:
$resource
你可以有一个这样的工厂:
abyssApp.factory('AbyssData', ['$resource', function($resource) {
return $resource('http://abyss.local/products.php')
}])
abyssApp.factory('abyssData', ['AbyssData', function(AbyssData) {
return AbyssData.query();
}])
var abyssApp = angular.module('abyssApp', []);
abyssApp.factory('abyssData', function($http) {
function abyssData() {
var self = this;
self.products = null;
self.getProducts = function(){
// return products if they are set already (cache)
if (self.products) { return self.products; }
$http.get('http://abyss.local/products.php').success(function(data){
self.products = data;
return self.products;
});
};
}
return new abyssData();
});
abyssApp.controller('ItemListCtrl', function($scope, abyssData) {
$scope.items = abyssData.getProducts();
});
请查看:$resource可能有三件事:
1) 显式声明依赖项:
abyssApp.controller('ItemListCtrl', function($scope, abyssData) {
为了
2) 要使用所需的值,工厂必须返回该值,因此最终应返回“result”变量。
尝试更改xhr请求中常见的变量名“result”,以防止重写
3) 要防止在返回之前访问数据,请尝试给出方法而不是值:
abyssApp.factory('abyssData', function($http) {
return {
get: function(successCallback){ //your callback function
$http.get('http://abyss.local/products.php')
.success(function(){
if(successCallback){
successCallback.apply(arguments);
}
});
}
}
}
要使用此更改,请执行以下操作:
$scope.items = abyssData;
为此
abyssData.get(function(data){
$scope.items = data;
});
可能有三件事:
1) 显式声明依赖项:
abyssApp.controller('ItemListCtrl', function($scope, abyssData) {
为了
2) 要使用所需的值,工厂必须返回该值,因此最终应返回“result”变量。
尝试更改xhr请求中常见的变量名“result”,以防止重写
3) 要防止在返回之前访问数据,请尝试给出方法而不是值:
abyssApp.factory('abyssData', function($http) {
return {
get: function(successCallback){ //your callback function
$http.get('http://abyss.local/products.php')
.success(function(){
if(successCallback){
successCallback.apply(arguments);
}
});
}
}
}
要使用此更改,请执行以下操作:
$scope.items = abyssData;
为此
abyssData.get(function(data){
$scope.items = data;
});
这里有一些编辑。请注意,我这样做没有真正检查,所以类型和错误是完全可能的,但它的要点应该是有意义的
var abyssApp = angular.module('abyssApp', []);
abyssApp.service('abyssData', function($http) {
this.products = $http.get('http://abyss.local/products.php');
});
abyssApp.controller('ItemListCtrl', function($scope, abyssData) {
abyssData.products.then(function(data) {
console.log(data);
$scope.items = data;
}).catch(function(err){console.log(err);});
});
我让它成为一个服务而不是一个工厂,因为你真的只需要一个服务(单件)。如果您要调用不同的URL,并且希望执行类似于product=new abysdata('potates')
之类的操作,那么工厂是合适的
一般来说,$http返回一个promise对象,它本身不是您需要的数据,而是解析为您需要的数据。这种承诺模式在angular中重复了很多次(并且在其他javascript场合越来越流行,因为它非常棒(IMO))。这意味着,在promise对象上,调用.then()方法,并在解析promise时传入要调用的函数。$http解析为XHR的结果。其他的承诺可以解决其他问题
在Promission.then stack的末尾,最好使用.catch()调用,因为在Promission中抛出的异常通常会进入bitbucket,除非您显式查找它们。这是承诺工作方式的一个普遍缺陷,意味着你必须小心例外情况。对于较旧的JS引擎,您需要将其更改为.then()'catch',因为catch在某些地方是一个有趣的词。但我90%确信任何阻塞.catch的JS环境都不会以角度运行。这里有一些编辑。请注意,我这样做没有真正检查,所以类型和错误是完全可能的,但它的要点应该是有意义的
var abyssApp = angular.module('abyssApp', []);
abyssApp.service('abyssData', function($http) {
this.products = $http.get('http://abyss.local/products.php');
});
abyssApp.controller('ItemListCtrl', function($scope, abyssData) {
abyssData.products.then(function(data) {
console.log(data);
$scope.items = data;
}).catch(function(err){console.log(err);});
});
我让它成为一个服务而不是一个工厂,因为你真的只需要一个服务(单件)。如果您要调用不同的URL,并且希望执行以下操作,则工厂将是合适的