在angularjs中嵌套资源调用的问题

时间:2017-03-10 20:44:21

标签: angularjs angular-resource

请原谅我,如果这在某种程度上是显而易见的,但我似乎无法在angularjs docs或SO上找到类似的东西。我有一个应用程序,其中有一个数据表,包括按月估算。我们正在实施一些可以将估算值从一个月拖放到另一个月的方法,以便进行一些快速更改。我遇到了一个奇怪的问题:

资源:

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);
}

因此在此代码中,估计创建/更新工作正常,但我无法在成功函数中调用源估计的任何$ resource调用。我收到错误TypeError: source.estimate.$delete is not a function如果我在该函数之外调用它(与目标保存/更新调用处于同一级别),它可以工作。

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

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)。

2 个答案:

答案 0 :(得分:0)

$ 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
});
  

因为调用promise的.then方法会返回一个新的派生promise,所以很容易创建一个promise链。

     

可以创建任意长度的链,并且由于可以使用另一个承诺(将进一步推迟其解析)来解决承诺,因此可以在链中的任何点暂停/推迟承诺的解析。这使得实现强大的API成为可能。

     

— AngularJS $q Service API Reference - Chaining Promises

答案 1 :(得分:0)

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