在for循环中运行时,如何调用$ resource等待完成?

时间:2013-11-12 13:16:14

标签: angularjs

我有以下循环检查网格中的每一行和 然后保存已更改的行:

for (var i = 0, len = $scope.grid.data.length; i < len; i++) {
    if (!angular.equals($scope.grid.data[i], $scope.grid.backup[i])) {

        var rowData = $scope.grid.data[i]
        var idColumn = $scope.entityType.toLowerCase() + 'Id';
        var entityId = rowData[idColumn];
        var entityResource = $resource('/api/:et/:id', { et: $scope.entityType }, { update: { method: 'PUT' } });
        $scope.grid.showMessage = true;
        $scope.grid.message = 'Saving Id: ' + entityId + ' ...';
        entityResource.update({ id: entityId }, $scope.grid.data[i],
            function (result) {
                angular.copy(result, $scope.grid.data[i]);
                angular.copy(result, $scope.grid.backup[i]);
                $timeout(function () {
                    $scope.grid.showMessage = false;
                    $scope.$broadcast('gridSetPristine');
                }, 1000);
            }, function (result) {
                var msg = result.data.exceptionMessage;
                $scope.grid.message = "Error saving grid data";
                $timeout(function () {
                    $scope.grid.showMessage = false;
                }, 5000);
            })
    }
}

如果所有行保存正常,这样做效果很好。但是我想改变它,以便在其中一个保存失败时停止。

我遇到的问题是更新功能直到稍后才会返回。如何进行更新,等待结果然后如果出现错误则继续或中断for循环?请注意,我使用的是1.2 RC3版本的Angular。另外我不介意这可能会很慢,因为每次按下保存按钮时,我的网格中只会少于三行,然后在for循环中调用代码。

2 个答案:

答案 0 :(得分:1)

我们有承诺和数组方法,让您的解决方案更轻松!耶: - )

以下是我们要做的事情:

  1. 我们将从网格数据中过滤掉所有尚未更新的对象。
  2. 我们将网格数据数组映射到更新服务器数据的请求数组,然后通过promises表示。看起来$ http比$资源更简单,所以我们将使用它。
  3. 我们将使用$ q.all来查看所有这些请求何时完成...或者如果一个请求被拒绝,我们就会抓住它。
  4. 示例代码:

    var entityIdColumn = $scope.entityType.toLowerCase() + 'Id';
    var requests = $scope.grid.data
      .filter(function(rowData, i) {
        return !angular.equals(rowData, $scope.grid.backup[i]);
      })
      .map(function(rowData, i) {
        var entityId = rowData[entityIdColumn];
        return $http.post('/api/' + $scope.entityType + '/' + entityId, rowData);
      });
    $q.all(requests).then(function(allResponses) {
      //if all the requests succeeded, this will be called, and $q.all will get an
      //array of all their responses.
      console.log(allResponses[0].data);
    }, function(error) {
      //This will be called if $q.all finds any of the requests erroring.
    });
    

    如果您不理解,则以下是对承诺的解释:http://sebastianfastner.de/javascript-promises-explained.html

答案 1 :(得分:0)

每次调用成功回调时,您应该执行更新要调用的函数中的资源的代码,您可以遵循以下方案:

$scope.saveNextRow = function(i) {
    ...
    entityResource.update(..,
        function (result) {
            ...
            if (++i < $scope.grid.data.length) {
                $scope.saveNextRow(i);
            }
        },
        function (result) {
            ...
        });
};

i = 0;
$scope.saveNextRow(i);