Angular:$resource update 仅在第二次调用时触发 PUT 请求 [英] Angular: $resource update fire PUT request on second call only

查看:26
本文介绍了Angular:$resource update 仅在第二次调用时触发 PUT 请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有自定义更新方法的资源:

I have a resource with a custom update method :

angular.module('user.resources', ['ngResource']).
factory('User', function($resource) {
  var User = $resource('/user/:id', {}, {
    update: {
      method: 'PUT'
    }
  });

  User.prototype.update = function(cb) {
    console.log('foo');
    return User.update({
      id: this._id
    }, angular.extend({}, this, {
      _id: undefined
    }), cb);
  };

我通过范围将此资源传递给自定义指令:

I'm passing this resource to a custom directive via scope:

directive('avatarUpload', function($http) {
  return {
    restrict: 'E',
    scope: {
      model: '='
    }, ...

我在 btn 单击时调用指令控制器中的更新方法:

and I'm calling the update method in the directive controller on a btn click:

$scope.model.update(function() {
  console.log('bar');
});

令我困惑的行为是第一次点击按钮打印foo"而不是bar",第二次点击它打印bar",然后是foo".再点击总是打印bar"然后打印foo".

The behavior which puzzle me atm is that clicking on the button the first time print 'foo' but not 'bar', clicking it a second time print 'bar', then 'foo'. Any more click always print 'bar' then 'foo'.

PUT 请求仅从第二次点击和之后的点击触发,而不会从第一次触发.

The PUT request is only fired from the second click and the ones after, never from the first.

注意:我一直在控制器中很好地使用资源更新方法,直到尝试从指令中调用它.我正在使用角 1.1.4我执行此资源传递是因为我希望该指令适用于不同类型的资源.

Note: I've been using that resource update method fine in controllers, until trying to call it from a directive. I'm using angular 1.1.4 I do this resource passing because I want the directive to work on different type of resource.

推荐答案

如果没有看到实时代码示例,很难确定,但我认为您正在使用 1.1.x 系列中的 AngularJS(所谓的不稳定分支")).如果是这样,您面临的问题与 AngularJS 中的新功能有关 - 1.1.4 版中引入的 HTTP 请求拦截器(这个 提交).

It is hard to say for sure without seeing live code example but I presume that you are using AngularJS from the 1.1.x series (so called "unstable branch"). If so, the problem you are facing is linked to the new feature in AngularJS - HTTP request interceptors introduced in version 1.1.4 (this commit).

新引入的请求拦截器是基于 $q(基于承诺)的,在 AngularJS 世界中,承诺仅作为 $digest 循环的一部分被解析.换句话说,您需要在AngularJS 世界"($digest 循环)中才能解决承诺.

The newly introduced request interceptors are $q-based (promise-based) and in AngularJS world promises are only resolved as part of the $digest cycle. In other words you need to be in the "AngularJS world" ($digest cycle) for the promises to be resolved.

使用基于承诺的请求拦截器,可以在进行 $http 调用之前解决承诺.如前所述,这个承诺只有在您进入 $digest 循环时才能解决.如果您从 AngularJS 外部(DOM 事件、setTimeout 等)启动 $http,则不会发生这种情况.

With the promise-based request interceptors there is a promise to be resolved before a $http call can be made. As as noted before this promise can only be resolved when you enter the $digest cycle. This won't happen if you are initiating the $http from outside of AngularJS (DOM event, setTimeout etc.).

在 AngularJS 中,$resource 基于 $http,所以上面的讨论也适用于 $resource.

In AngularJS $resource is based on $http so the above discussion apply to the $resource as well.

因此,假设上述假设是正确的,并且您正在从 AngularJS 外部启动 $resource 调用(您正在谈论自定义指令,所以我打赌 DOM 事件)您应该简单地将 $resource 调用包装到 scope.$apply 中.

So, presuming that the above assumptions are correct and you are initiating the $resource call from outside of AngularJS (you are talking about a custom directive so I would bet on a DOM event) you should simply wrap the $resource call into scope.$apply.

请注意,将 $resource 调用包装到 $timeout(如另一个回复中所建议的),同时将修复"您的问题(它会强制 $digest循环,因此承诺将得到解决)这不是正确的方法.问题是它会强制浏览器离开当前的 JavaScript 上下文并白白进入重绘上下文.它会使您的应用程序变慢,并可能导致 UI 闪烁.

Please note that wrapping the $resource call into $timeout (as suggested in another response), while will "fix" your issue (it will force a $digest loop and thus promises will get resolved) it is not the correct approach. The problem is that it will force a browser to leave the current JavaScript context and enter the repaint context for nothing. It will make your application slower and may result in UI flickering.

这篇关于Angular:$resource update 仅在第二次调用时触发 PUT 请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆