我一直在尝试AngularJS进行实验项目,我遇到了这个问题。 在我的HTML中,我想显示一个项目列表
的index.html
<h1>Some list</h1>
<div ng-controller="datlist">
<div ng-repeat="item in items">
<div>Item description: {{item.description}}</div>
<div>Item name: {{item.name}}</div>
</div>
</div>
起初我使用一个简单的控制器来获取信息并使用这个来更新视图:
controllers.js(原创)
function datlist($scope,$http){
$http({method: 'GET', url: 'http://localhost:61686/getdatlist?format=json', headers: {'Access-Control-Allow-Origin': 'localhost:*'}}).
success(function(data, status, headers, config) {
$scope.items=data.itemsToReturn;
console.log(data);
}).
error(function(data, status, headers, config) {
console.log("fail");
});
}
这很好用,我可以得到物品清单。同时,通过更改我的结构以使用工厂发出相同的请求并将其绑定到$ scope.items它不起作用。我尝试了很多$ watch的变种,但是我无法更新$ scope.items。我发现了一些关于$ apply的内容,但我真的无法理解如何使用它。
controllers.js(新的)
var datModule = angular.module('datModule',[]);
datModule.controller('datlist', function ($scope, datfactory){
$scope.items = datfactory.getlist();
$scope.$watch($scope.items, $scope.items = datfactory.getlist());
});
datModule.factory('datfactory', function ($http){
var factory = {};
factory.getlist = function(){
$http({method: 'GET', url: 'http://localhost:61686/getdatlist?format=json', headers: {'Access-Control-Allow-Origin': 'localhost:*'}}).
success(function(data, status, headers, config) {
console.log(data.itemsToReturn); //I get the correct items, all seems ok here
return data.itemsToReturn;
}).
error(function(data, status, headers, config) {
console.log("fail");
});
}
return factory;
});
任何关于此的想法都会很棒。 PS:我发现很多帖子都在谈论这个问题,但没有一个能帮我找到完整的解决方案。
由于
答案 0 :(得分:18)
使用手表有点难看。
试试这个:
datModule.factory('datfactory', function ($http, $q){
this.getlist = function(){
return $http.get('http://localhost:61686/getdatlist?format=json',{'Access-Control-Allow-Origin': 'localhost:*'})
.then(function(response) {
console.log(response); //I get the correct items, all seems ok here
return response.data.itemsToReturn;
});
}
return this;
});
datModule.controller('datlist', function ($scope, datfactory){
datfactory.getlist()
.then(function(arrItems){
$scope.items = arrItems;
});
});
这就是你如何使用promise来处理异步问题。
更新(2015年1月15日):现在更时尚!
答案 1 :(得分:8)
该问题与范围摘要周期无关。您正试图直接从回调内部返回,这不是异步的。
我建议您使用承诺,或直接返回http承诺。
var factory = {};
factory.getlist = function(){
return $http({method: 'GET', url: 'http://localhost:61686/getdatlist?format=json', headers: {'Access-Control-Allow-Origin': 'localhost:*'}});
}
return factory;
直接返回承诺,并在factory.getlist().success()
或者,如果您想围绕请求包装其他逻辑,请使用您自己的承诺。
var datModule = angular.module('datModule',[]);
datModule.controller('datlist', function ($scope, datfactory){
$scope.items = [];
datfactory.getlist().then(function(data) { $scope.items = data });
});
datModule.factory('datfactory', function ($http, $q){
var factory = {};
factory.getlist = function(){
var defer = $q.defer();
$http({method: 'GET', url: 'http://localhost:61686/getdatlist?format=json', headers: {'Access-Control-Allow-Origin': 'localhost:*'}}).
success(function(data) {
// alter data if needed
defer.resolve(data.itemsToReturn);
}).
error(function(data, status, headers, config) {
defer.reject();
});
return defer.promise;
}
return factory;
});
答案 2 :(得分:1)
它看起来很完美,但您可以像这样使用$apply
。
datModule.controller('datlist', function ($scope, datfactory){
$scope.$apply(function() {
$scope.items = datfactory.getlist();
});
});
答案 3 :(得分:1)
在调用$ http
之前尝试在控制器上初始化$scope.items = [];
我希望它可以帮到你。
答案 4 :(得分:0)
我认为这个问题的另一个优雅解决方案可能是 - 如果您使用其中一个路由库,在我的情况下它是UI路由器,但也可能是ngRoute,正在使您的控制器依赖于承诺,例如。 将一个resolve属性添加到适当的状态/路由,这个状态/路由不会让控制器加载,直到承诺解决并且数据准备就绪,所以在你的配置中:
.state('datpage', {
url: '/datpage',
controller: 'DatpageController',
resolve:{
datData: function (datfactory) {
return datDataService.getData("datDataParam");
}]
},
templateUrl: 'views/datpage.html'
})
在控制器中注入datData依赖项,您可以将其直接应用于$ scope:
.controller('DatpageController', function ($scope,datData) {
$scope.datPageData = datData; ...