我最近发布了一篇关于我在SO面临的问题的详细描述。由于我无法发送一个实际的$http请求,所以我使用timeout来模拟异步行为。在@Gloopy的帮助下,从我的模型到视图的数据绑定工作正常
现在,当我使用$http而不是$timeout(在本地测试)时,我可以看到异步请求是成功的,数据在我的服务中被json响应填充。但是,我的观点并没有更新。
在这里更新Plunkr
我最近发布了一篇关于我在SO面临的问题的详细描述。由于我无法发送一个实际的$http请求,所以我使用timeout来模拟异步行为。在@Gloopy的帮助下,从我的模型到视图的数据绑定工作正常
现在,当我使用$http而不是$timeout(在本地测试)时,我可以看到异步请求是成功的,数据在我的服务中被json响应填充。但是,我的观点并没有更新。
在这里更新Plunkr
当前回答
与此相关,我也遇到过类似的问题,但不是用Angular的get或post,而是用第三方的扩展(在我的例子中是Chrome extension)。 我面临的问题是,Chrome扩展不会返回然后(),所以我无法做到上面的解决方案,但结果仍然是异步的。 因此,我的解决方案是创建一个服务,然后进行回调
app.service('cookieInfoService', function() {
this.getInfo = function(callback) {
var model = {};
chrome.cookies.get({url:serverUrl, name:'userId'}, function (response) {
model.response= response;
callback(model);
});
};
});
然后在控制器中
app.controller("MyCtrl", function ($scope, cookieInfoService) {
cookieInfoService.getInfo(function (info) {
console.log(info);
});
});
希望这篇文章可以帮助其他有同样问题的人。
其他回答
简单点。这很简单
在您服务期间退货承诺(在您服务期间无需使用) 在你的控制器中使用then
演示。http://plnkr.co/edit/cbdG5p?p=preview
var app = angular.module('plunker', []);
app.factory('myService', function($http) {
return {
async: function() {
return $http.get('test.json'); //1. this returns promise
}
};
});
app.controller('MainCtrl', function( myService,$scope) {
myService.async().then(function(d) { //2. so you can use .then()
$scope.data = d;
});
});
这里有一个Plunk,可以做你想要的:http://plnkr.co/edit/TTlbSv?p=preview
其思想是直接使用承诺及其“then”函数来操作和访问异步返回的响应。
app.factory('myService', function($http) {
var myService = {
async: function() {
// $http returns a promise, which has a then function, which also returns a promise
var promise = $http.get('test.json').then(function (response) {
// The then function here is an opportunity to modify the response
console.log(response);
// The return value gets picked up by the then in the controller.
return response.data;
});
// Return the promise to the controller
return promise;
}
};
return myService;
});
app.controller('MainCtrl', function( myService,$scope) {
// Call the async method and then do stuff with what is returned inside our own then function
myService.async().then(function(d) {
$scope.data = d;
});
});
这里有一个稍微复杂一点的版本,它缓存了请求,所以您只在第一次发出请求(http://plnkr.co/edit/2yH1F4IMZlMS8QsV9rHv?p=preview):
app.factory('myService', function($http) {
var promise;
var myService = {
async: function() {
if ( !promise ) {
// $http returns a promise, which has a then function, which also returns a promise
promise = $http.get('test.json').then(function (response) {
// The then function here is an opportunity to modify the response
console.log(response);
// The return value gets picked up by the then in the controller.
return response.data;
});
}
// Return the promise to the controller
return promise;
}
};
return myService;
});
app.controller('MainCtrl', function( myService,$scope) {
$scope.clearData = function() {
$scope.data = {};
};
$scope.getData = function() {
// Call the async method and then do stuff with what is returned inside our own then function
myService.async().then(function(d) {
$scope.data = d;
});
};
});
我读过http://markdalgleish.com/2013/06/using-promises-in-angularjs-views/ [AngularJS允许我们通过直接在作用域上放置承诺来简化我们的控制器逻辑,而不是在成功回调中手动处理已解析的值。]
如此简单和方便:)
var app = angular.module('myApp', []);
app.factory('Data', function($http,$q) {
return {
getData : function(){
var deferred = $q.defer();
var promise = $http.get('./largeLoad').success(function (response) {
deferred.resolve(response);
});
// Return the promise to the controller
return deferred.promise;
}
}
});
app.controller('FetchCtrl',function($scope,Data){
$scope.items = Data.getData();
});
希望这对你有所帮助
在将UI绑定到数组时,您需要确保通过将长度设置为0并将数据推入数组来直接更新相同的数组。
而不是这个(设置一个不同的数组引用数据,你的UI不会知道):
myService.async = function() {
$http.get('test.json')
.success(function (d) {
data = d;
});
};
试试这个:
myService.async = function() {
$http.get('test.json')
.success(function (d) {
data.length = 0;
for(var i = 0; i < d.length; i++){
data.push(d[i]);
}
});
};
下面是一个演示,显示了设置一个新数组与清空和添加到现有数组之间的区别。我不能让你的plnkr工作,但希望这对你有用!
与此相关,我也遇到过类似的问题,但不是用Angular的get或post,而是用第三方的扩展(在我的例子中是Chrome extension)。 我面临的问题是,Chrome扩展不会返回然后(),所以我无法做到上面的解决方案,但结果仍然是异步的。 因此,我的解决方案是创建一个服务,然后进行回调
app.service('cookieInfoService', function() {
this.getInfo = function(callback) {
var model = {};
chrome.cookies.get({url:serverUrl, name:'userId'}, function (response) {
model.response= response;
callback(model);
});
};
});
然后在控制器中
app.controller("MyCtrl", function ($scope, cookieInfoService) {
cookieInfoService.getInfo(function (info) {
console.log(info);
});
});
希望这篇文章可以帮助其他有同样问题的人。