为什么我必须将 $promise 与 $resource 一起使用?
Why do I have to use $promise with $resource?
诚然,我对 Angular 比较陌生,但我已经摆脱了使用 ngResource 进行 REST 调用的困境。
我遵循了一个工厂模式,这个模式看起来比较普遍。
但是我只能使用 $promise.then 访问 REST 响应。我知道你不需要 $resource.
所以我有这个工厂...
var LookupsService = angular.module('LookupsService', ['ngResource']);
LookupsService.factory('Lookups', ['$resource',
function ($resource) {
return $resource('http://localhost:5001/api/lookups', {});
}]);
这失败了(未定义)
alert(Lookups.get().foo);
但这很好
Lookups.get()
.$promise
.then(function (lookups) {
alert(lookups.foo);
});
我显然在这里遗漏了一些东西。某种小学生错误 ;-)
更新
感谢您的帮助 - 现在很清楚了。我给@fikkatra打了勾,因为她的回答和片段很清晰。但几乎所有的答案都是有帮助的。我必须小心使用 Alert 进行调试!
您不必,也不应该将 $promise
与 $resource
结合使用。 $resource
服务可以这样使用:
(function() {
'use strict';
angular
.module('app')
.factory('MyService', MyService);
MyService.$inject = ['$resource'];
function MyService($resource) {
return $resource('my/url/:id', {id: "@id"}, {
'query': { isArray: false },
'update': { method: "put" }
});
}
})();
它会返回几个 HTTP 方法,您可以在代码中使用这些方法,而无需自己编写。要使用它们,您可以这样做:
function getActionTypes(){
MyService.query(
function success(result){
// do stuff with result
},
function failure(result){
console.error(result);
});
}
对承诺使用 alert
无效,即它不会显示承诺中的结果。但是,angular 被设计为直接使用 $resource
服务绑定到作用域。这意味着您可以将 $resource
结果绑定到范围对象,并且 angular 将在应用绑定时考虑范围对象是一个承诺。这就是为什么 alert(resourceResult)
不起作用,但 $scope.myObj = resourceResult;
(然后将其绑定到视图中)会起作用的原因。
插入代码片段以更清楚地解释事情:
var app = angular.module('myapp', ['ngResource']);
app.controller('myctrl', function($scope, $resource) {
//this won't work:
//alert("won't work: " + $resource('https://api.github.com/users/fikkatra').get());
//but this will work
$resource('https://api.github.com/users/fikkatra').get().$promise.then(function(user) {
alert("will work: " + user.login);
});
//directly assigning $resource result to scope will work:
$scope.user = $resource('https://api.github.com/users/fikkatra').get();
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular-resource.js"></script>
<div ng-app="myapp" ng-controller="myctrl">
{{user.login}}
</div>
根据 specification,您可以按照这个小代码片段中的概述传递成功回调。
var User = $resource('/user/:userId', {userId:'@id'});
var user = User.get({userId:123}, function() {
user.abc = true;
user.$save();
});
资源完成时将调用成功回调函数。
或者,您可以将 promise 语法与 get()
结合使用,除非您不需要根据您的示例添加自己的 promise。相反,您可以简单地执行以下操作:
Lookups.get()
.then(function (lookups) {
alert(lookups.foo);
});
这是因为get()
returns一个承诺。当 promise 被成功评估时 then()
将被调用
您实际上没有使用 $promise,只要您愿意,它就可用。
代码笔:http://codepen.io/troylelandshields/pen/bpLoxE
angular.module('app', ['ngResource'])
.service('exampleSvc', function($resource){
return $resource('http://jsonplaceholder.typicode.com/posts/1', {});
})
.controller('exampleCtrl', function(exampleSvc, $scope){
$scope.result = exampleSvc.get();
exampleSvc.get().$promise.then(function(val){
//Do some other logic here on the val
$scope.promiseResult = val;
});
});
您还可以将 .get() 的结果分配给作用域上的一个变量,当请求被解析时,结果将被填充(在上面的第一个例子中)。这适用于将数据分配给范围内的对象,该对象最终将显示在页面上,但对于需要使用 .get() 的结果执行其他操作的其他情况可能效果不佳。
诚然,我对 Angular 比较陌生,但我已经摆脱了使用 ngResource 进行 REST 调用的困境。
我遵循了一个工厂模式,这个模式看起来比较普遍。
但是我只能使用 $promise.then 访问 REST 响应。我知道你不需要 $resource.
所以我有这个工厂...
var LookupsService = angular.module('LookupsService', ['ngResource']);
LookupsService.factory('Lookups', ['$resource',
function ($resource) {
return $resource('http://localhost:5001/api/lookups', {});
}]);
这失败了(未定义)
alert(Lookups.get().foo);
但这很好
Lookups.get()
.$promise
.then(function (lookups) {
alert(lookups.foo);
});
我显然在这里遗漏了一些东西。某种小学生错误 ;-)
更新
感谢您的帮助 - 现在很清楚了。我给@fikkatra打了勾,因为她的回答和片段很清晰。但几乎所有的答案都是有帮助的。我必须小心使用 Alert 进行调试!
您不必,也不应该将 $promise
与 $resource
结合使用。 $resource
服务可以这样使用:
(function() {
'use strict';
angular
.module('app')
.factory('MyService', MyService);
MyService.$inject = ['$resource'];
function MyService($resource) {
return $resource('my/url/:id', {id: "@id"}, {
'query': { isArray: false },
'update': { method: "put" }
});
}
})();
它会返回几个 HTTP 方法,您可以在代码中使用这些方法,而无需自己编写。要使用它们,您可以这样做:
function getActionTypes(){
MyService.query(
function success(result){
// do stuff with result
},
function failure(result){
console.error(result);
});
}
对承诺使用 alert
无效,即它不会显示承诺中的结果。但是,angular 被设计为直接使用 $resource
服务绑定到作用域。这意味着您可以将 $resource
结果绑定到范围对象,并且 angular 将在应用绑定时考虑范围对象是一个承诺。这就是为什么 alert(resourceResult)
不起作用,但 $scope.myObj = resourceResult;
(然后将其绑定到视图中)会起作用的原因。
插入代码片段以更清楚地解释事情:
var app = angular.module('myapp', ['ngResource']);
app.controller('myctrl', function($scope, $resource) {
//this won't work:
//alert("won't work: " + $resource('https://api.github.com/users/fikkatra').get());
//but this will work
$resource('https://api.github.com/users/fikkatra').get().$promise.then(function(user) {
alert("will work: " + user.login);
});
//directly assigning $resource result to scope will work:
$scope.user = $resource('https://api.github.com/users/fikkatra').get();
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular-resource.js"></script>
<div ng-app="myapp" ng-controller="myctrl">
{{user.login}}
</div>
根据 specification,您可以按照这个小代码片段中的概述传递成功回调。
var User = $resource('/user/:userId', {userId:'@id'});
var user = User.get({userId:123}, function() {
user.abc = true;
user.$save();
});
资源完成时将调用成功回调函数。
或者,您可以将 promise 语法与 get()
结合使用,除非您不需要根据您的示例添加自己的 promise。相反,您可以简单地执行以下操作:
Lookups.get()
.then(function (lookups) {
alert(lookups.foo);
});
这是因为get()
returns一个承诺。当 promise 被成功评估时 then()
将被调用
您实际上没有使用 $promise,只要您愿意,它就可用。
代码笔:http://codepen.io/troylelandshields/pen/bpLoxE
angular.module('app', ['ngResource'])
.service('exampleSvc', function($resource){
return $resource('http://jsonplaceholder.typicode.com/posts/1', {});
})
.controller('exampleCtrl', function(exampleSvc, $scope){
$scope.result = exampleSvc.get();
exampleSvc.get().$promise.then(function(val){
//Do some other logic here on the val
$scope.promiseResult = val;
});
});
您还可以将 .get() 的结果分配给作用域上的一个变量,当请求被解析时,结果将被填充(在上面的第一个例子中)。这适用于将数据分配给范围内的对象,该对象最终将显示在页面上,但对于需要使用 .get() 的结果执行其他操作的其他情况可能效果不佳。