使用angular的$ resource资源承诺,我可以将promise直接分配给变量,并在成功函数中将promise的结果分配给varible。我想知道我是否能用$ q实现同样的目标?
实施例
.service("rest", function($resource){
return {
user: $resource( "http://some.com/url")
}
})
.controller("myCtrl", function($scope, rest){
$scope.user = rest.user.get(); <-- This is what I want to be able to do with $q
})
答案 0 :(得分:3)
$resource
界面专门用于允许这种“未来”行为。当您致电.get()
时,它会返回一个占位符对象,该对象将在可用时填充数据。
因为$resource
是一个内部Angular工厂,它知道何时触发摘要周期,这使得您似乎可以从头开始使用$scope.user
。实际上,在服务器发出HTTP响应之前,不会填充数据。
这种机制只能用于Angular对作用域进行脏检查的方式。当异步发生时,需要让Angular知道它应该检查是否有任何变化,并且需要更新它的视图。
当数据从我们的HTTP响应中到达时,$resource
工厂负责让Angular知道。这意味着$scope.user
对象一到达即会显示在您的视图中。 $resource
负责在异步事件发生时使事情发生。在这种情况下,异步事件是与数据一起到达的HTTP响应。
使用promises时,您负责在异步事件发生时使事情发生。承诺特定于Angular,因此promises有一个通用接口,用于处理可能发生在promise中的不同异步事件。当其中一个发生时,这是你的工作,这就是为什么简短的答案是否定的。
然而,如果您正在实施工厂/服务/提供商,可能需要此行为,则可能。
让我们创建一个火箭工厂,创建火箭实例,稍后将使用$resource
工厂以与$q
相同的方式添加其部件。
app.factory('Rocket', function(Junkyard) {
return function(name) {
var rocket = {};
rocket.name = name || 'Boring Rocket';
rocket.parts = [];
rocket.promise = Junkyard.getParts();
// Junkyard.getParts returns a $q promise
// which will be resolved with an object
// of things that can be attached to the rocket.
//
// It might look something like this
// [
// { name: "thrusters", "quantity": 3 },
// { name: "engines", "quantity": 100 },
// { name: "robots", "quantity": 2 }
// ]
rocket.promise.then(function(parts) {
parts.forEach(function(part) {
rocket.parts.push(part);
});
});
return rocket;
};
});
现在我们可以以与$resource
:
function MyController($scope, Rocket) {
$scope.rocket = Rocket('Top Rocket');
// we can use $scope.rocket here!
$scope.rocket.name = 'Even Better Rocket';
// but it won't have the properties from
// Junkyard.getParts yet.
}
我们可以将这些值直接模板化到我们的视图中。
<section ng-controller='MyController'>
<h1 ng-bind='rocket.name'></h1>
<table>
<th>
<td>Name</td>
</th>
<th>Description</th>
<tr ng-repeat='part in rocket.parts'>
<td ng-bind='part.name'></td>
<td ng-bind='part.description'></td>
</tr>
</table>
</section>
一旦promise解析,属性将被添加到火箭中,范围摘要将由$q
触发,因为$q
知道刚刚发生了异步事件。
答案 1 :(得分:0)
从Angular中删除了将promises直接分配给变量并在模板中呈现它们的功能。看到这个重大变化:Templates no longer automatically unwrap promises。相反,当解析或拒绝承诺时,您必须在回调中分配scope属性。
答案 2 :(得分:0)
您可以,只返回一个更新的对象而不是一个promise。 jsfiddle
var getUser = function(base) {
var user = base || {};
// replace with actual request
$timeout(function() {
// make sure to use angular.copy so the same object is used
angular.copy({
id: 1,
username: 'anon',
roles: [
{ id: 1, title: 'user' },
{ id: 2, title: 'admin' },
{ id: 3, title: 'editor' }
]
}, user);
}, 3000);
return user;
};
$scope.user = getUser({roles: []});
答案 3 :(得分:0)
这样做(它是一个coffeescript),
service.getSomeData = () ->
data = {}
$http.get("/getSomeData").then (resp) ->
angular.copy(resp.data, data)
return data
在控制器中你可以这样做
$scope.data = service.getSomeData()