angularjs 中的嵌套资源调用问题

Issue with nested resource calls in angularjs

如果这在某种程度上很明显,请原谅,但我似乎无法在 angularjs 文档或 SO 上找到任何类似的东西。我有一个应用程序,其中有 table 数据,包括按月估算。我们正在实施一些功能,您可以将估算值从一个月拖放到另一个月,以此作为快速更改的一种方式。我 运行 遇到了一个奇怪的问题:

资源:

function updatableResource(url){
  return $resource(url+":id/", {id: '@id'},
    {
      'update': {
        method:'PUT',
      },
    }
  );
}

// in API definition file
Estimate: foo.updatableResource('<URL>'),

工作正常,我可以正常调用 $update$save 没有问题

虽然在这种情况下,我需要同时编辑两个东西,甚至可能删除一个。所以在我做第二个之前我需要知道第一个是否成功。例如,如果我将一个估算从一个月移动到另一个没有估算的月份,我会先进行新估算,然后删除旧估算。我想我可以做这样的事情:

// source and target are objects that each contain an estimate from a different month.

successFunc = function() {
    source.estimate.$delete(
        function() {
            <refresh stuff>
        },
        function(rejection) {
            alert("Unable to delete source estimate.");
        }
    );
};

errorFunc = function(rejection) {
    <undo stuff>
    alert("Unable to add money to target estimate.");
};

// POST if new, PUT if updating
if (isNewEstimate) {
    target.estimate.$save(successFunc, errorFunc);
} else {
    target.estimate.$update(successFunc, errorFunc);
}

所以在这段代码中,估计 creation/update 工作正常,但我无法在成功函数中对源估计调用任何 $resource 调用。我收到错误 TypeError: source.estimate.$delete is not a function 如果我在该函数外调用它(与目标 save/update 调用处于同一级别)它仍然有效。

在我的研究中,我发现了一些有用的东西:

Api.Estimate.delete(source.estimate, 
<success and failure functions>
...

删除成功了,但似乎没有其他东西可以识别删除,我需要进行昂贵的手动重新查询才能使其正常工作。因为它在回调函数中,所以作用域有什么奇怪的地方吗?我只是不明白为什么它不能在那个函数中工作...

编辑:

经进一步测试,似乎是对象本身的问题:

source.estimate
Object
    amount: 12345
    date: "2017-02-25"
    foo: "ABC"
    id: 4715
    bar: 987
    baz: 123
    __proto__: Object

target.estimate
d
    $promise: undefined
    $resolved: true
    amount: 12345
    date: "2017-03-25"
    foo: "ABC"
    id: 4716
    bar: 987
    baz: 123
    __proto__: Object

因此,d 类型的目标对象似乎可以工作,而只是标准对象的源对象却不能。如果我反转拖动方向,我会得到相同类型的结果。源始终是一个对象,目标始终是 d(我认为这是因为缩小了 JS)。

$resource 对象的实例方法是 Promise,可以用标准链接方法链接:

$scope.resource1 = updatableResource().get({id: 1});
$scope.resource2 = updatableResource().get({id: 2});

$q.all([$scope.resource1.$promise, $scope.resource2.$promise])
  .then(function(resArray) {
     var res1 = resArray[0];
     var res2 = resArray[1];
     //Process results
     //Return promise to chain
     return $q.all([res1.$update(), res2.$update()]);
}).then(function(resArray) {
     var res1 = resArray[0];
     var res2 = resArray[1];
     //Do next thing
});

Because calling the .then method of a promise returns a new derived promise, it is easily possible to create a chain of promises.

It is possible to create chains of any length and since a promise can be resolved with another promise (which will defer its resolution further), it is possible to pause/defer resolution of the promises at any point in the chain. This makes it possible to implement powerful APIs.

— AngularJS $q Service API Reference - Chaining Promises

问题实际上与我用来获取对象的插件有关。由于某种原因,它正在破坏其中一个,虽然它具有相同的属性,但它不再是一个合适的 $resource,这就是我无法调用该函数的原因。由于我调用某些函数的顺序,它似乎与调用布局有关。