我尝试从服务加载数据并使用$ q更新视图,但它无法正常工作。如果我将http调用放在控制器中,它可以工作,但我更喜欢它是服务的一部分。
有任何帮助吗?另外,有没有更好的方法来做这个而不是承诺?
下面的演示和代码。
---------- Fiddle Demo Link ----------
查看
<div ng-init="getData()">
<div ng-repeat="item in list">{{item.name}}</div>
</div>
控制器
.controller('ctrl', ['$scope', 'dataservice', '$q', function ($scope, dataservice, $q) {
$scope.list = dataservice.datalist;
var loadData = function () {
dataservice.fakeHttpGetData();
};
var setDataToScope = function () {
$scope.list = dataservice.datalist;
};
$scope.getData = function () {
var defer = $q.defer();
defer.promise.then(setDataToScope());
defer.resolve(loadData());
};
}])
服务
.factory('dataservice', ['$timeout', function ($timeout) {
// view displays this list at load
this.datalist = [{'name': 'alpha'}, {'name': 'bravo'}];
this.fakeHttpGetData = function () {
$timeout(function () {
// view should display this list after 2 seconds
this.datalist = [{'name': 'charlie'}, {'name': 'delta'}, {'name': 'echo'}];
},
2000);
};
return this;
}]);
答案 0 :(得分:1)
首先,不要以这种方式使用ng-init
。根据文档:
ngInit的唯一合适用途是对特殊属性进行别名处理 ngRepeat的内容,如下面的演示所示。除了这种情况,你应该 使用控制器而不是ngInit来初始化作用域上的值。
其次,在这种情况下,承诺是完美的选择,但您不需要触摸$q
,因为$http
来电会为您回复承诺。
要正确执行此操作,只需返回服务中的$http
结果:
this.getDataFromService = function() {
return $http(/* http call info */);
};
然后,在你的控制器里面:
dataservice.getDataFromService().then(function(result){
$scope.list = result.data;
});
此处还有更新的小提琴:http://jsfiddle.net/RgwLR/
请记住,$q.when()
只是将给定值包装在一个承诺中(模仿示例中$http
的响应)。
答案 1 :(得分:1)
不需要ngInit或$ q。这就是你应该怎么做的。
您也不应将dataservice.list
公开给控制器。这应该是dataservice
的私有,它将包含大部分逻辑,以确定是将控制器发送到现有列表还是更新列表然后发送它。
angular.module('app', [])
.controller('ctrl', ['$scope', 'dataservice', function ($scope, dataservice) {
loadData();
function loadData() {
dataservice.fakeHttpGetData().then(function (result) {
$scope.list = result;
});
}
}])
.factory('dataservice', ['$timeout', function ($timeout) {
var datalist = [
{
'name': 'alpha'
},
{
'name': 'bravo'
}
];
this.fakeHttpGetData = function () {
return $timeout(function () {
// Logic here to determine what the list should be (what combination of new data and the existing list).
datalist = [
{
'name': 'charlie'
},
{
'name': 'delta'
},
{
'name': 'echo'
}
];
return datalist;
},
2000);
};
return this;
}]);