我遇到一个问题,即控制器调用服务函数getMyList但myLists尚未填充,因为$ http调用需要一些时间才能完成。
如何解决此问题?
这是我的代码段:
服务
app.factory('myService', function($http) {
var myList = [];
$http.get("http://myService/json.data").then(function (resp) {
myLists = resp.data;
});
return {
getMyList: function (name) {
for (var i = 0; i < myLists.length; i++) {
if (myList[i].name == name) {
return myLists[i];
}
}
}
}
}
控制器:
app.controller('MainCtrl', function( myService,$scope) {
var testName = "test"
myService.getMyList(testName).then(function(resp) {
// do something with resp data
});
});
答案 0 :(得分:2)
首先需要修复拼写错误,并选择更好的命名。然后你需要返回一个元素的承诺而不是一个元素(顺便说一句,这是控制器所期望的):
app.factory('myService', function($http) {
// this defines a promise which, when resolved, contains an array of elements
var listPromise = $http.get("http://myService/json.data").then(function(resp) {
return resp.data;
});
return {
// this returns a promise which, when resolved, contains the element with the given name
getElementFromList: function(name) {
return listPromise.then(function(list) {
return list.filter(function(element) {
return element.name === name;
})[0];
});
}
};
});
答案 1 :(得分:0)
每个HTTP调用都会以角度返回promise
,因此在您的服务中只返回HTTP调用并返回promise
。
然后在您的控制器中,您可以使用then
和error
回拨来处理来自service
或api
来电的回复。
<强>工厂:强>
app.factory('myService', function($http) {
var myList = [];
return {
getMyList: function (name) {
$http.get("http://myService/json.data")
}
}
}
<强>控制器:强>
app.controller('MainCtrl', function( myService,$scope) {
var testName = "test"
myService.getMyList()
.then(function successCallback(resp) // Success call back
{
if(resp.data)
{
myLists = resp.data;
for (var i = 0; i < myLists.length; i++) {
if (myList[i].name == testName) { // you can use your testName here itself.
return myLists[i];
}
}
}
},
function errorCallback(resp) // Error call back
{
console.log(resp)
});
});
答案 2 :(得分:0)
如果您正在使用某些客户端路由器实现:请查看Route.Resolve
和Ui.Router
实现的angular
.module('test', [])
.constant('API', 'https://jsonplaceholder.typicode.com')
.factory("PostResolved", function($http, API) {
var result = [];
$http
.get(API + '/posts/1')
.then(function(response) {
result.push(response.data);
})
;
return result;
})
.controller('TestCtrl', function($scope, PostResolved) {
$scope.posts = PostResolved;
})
;
。
如果你没有任何路由器,那么,你可以做一个小技巧......只需从你的工厂返回一个对象引用,并在解决时,用预期的方法填充该对象值:
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<section ng-app="test">
<article ng-controller="TestCtrl">
<div ng-repeat="post in posts">
<h1 ng-bind="post.title"></h1>
</div>
</article>
</section>
&#13;
Quantity
&#13;
答案 3 :(得分:0)
为什么不使用以下内容:
app.factory('myService', function($http) {
return {
getMyList: function (name) {
var myList = [];
$http.get("http://myService/json.data").then(function (resp) {
myLists = resp.data;
});
scope.$evalAsync(function () {
for (var i = 0; i < myLists.length; i++) {
if (myList[i].name == name) {
return myLists[i];
}
}
});
}
}
}
&#13;
答案 4 :(得分:0)
我设法通过使用$ timeout来解决这个问题。任何有更好建议的人都会告诉我。我无法获得范围。$ evalAsync工作
服务
app.factory('myService', function($http, $timeout) {
var lists = [];
$http.get("http://myService/json.data").then(function (resp) {
lists = resp.data;
});
return {
getMyList: function (name) {
return $timeout(function() {
for (var i = 0; i < lists.length; i++) {
if (lists[i].name == name) {
return lists[i];
}
}
}, 2000)
}
}
控制器
app.controller('MainCtrl', function( myService,$scope) {
var testName = "test"
myService.getMyList(testName).then(function(resp) {
// do something with resp data
});
});