无法在Angular UI Grid的可扩展行中保存行。

6

我尝试使用行保存功能结合可展开网格。目标是能够独立保存子网格行,而不影响父行。

$scope.gridOptions = {
  expandableRowTemplate: 'components/grid/orderLineTemplate.html',
  expandableRowHeight: 150,

  expandableRowScope: {
    subGridVariable: 'subGridScopeVariable'

  },
  columnDefs: [
    {field: '_id'},
    {field: 'number'}
  ]
};

$http.get(ORDER_API)
  .success(function (data) {
    for (var i = 0; i < data.length; i++) {
      var rowScope = data[i];
      rowScope.subGridOptions = {
        appScopeProvider: $scope,
        columnDefs: [
          {field: 'amount'},
          {field: 'packageAmount'},
          {field: 'carrierAmount'}
        ],
        data: rowScope.orderLines,
        saveRow : $scope.saveRow
      }
    }
    $scope.gridOptions.data = data;
  });

$scope.gridOptions.onRegisterApi = function (gridApi) {
  $scope.gridApi = gridApi;
  gridApi.rowEdit.on.saveRow($scope, $scope.saveRow);
};

$scope.saveRow = function (order) {
  var promise = $q.defer();
  $scope.gridApi.rowEdit.setSavePromise(order, promise.promise);
  if(order.number) {
    $http.put(ORDER_API + '/' + order._id, order).success(function () {
      promise.resolve();
    }).error(function () {
      promise.reject();
    });
  }

}
});

当我编辑父行中的字段时,saveRow函数被正确地调用。但是,当我编辑子行中的字段时,在控制台中会出现以下消息:
“在触发saveRow事件时未返回Promise,可能没有人监听此事件,或事件处理程序未返回Promise”
对于展开的子行,saveRow从未被调用。

3个回答

3

您需要注册子网格API。每个网格都有自己独立的API实例,您可以使用它来与其通信:

rowScope.subGridOptions = {
  appScopeProvider: $scope,
  columnDefs: [
    {field: 'amount'},
    {field: 'packageAmount'},
    {field: 'carrierAmount'}
  ],
  data: rowScope.orderLines,
  saveRow : $scope.saveRow,
  onRegisterApi: function (gridApi) {
    gridApi.rowEdit.on.saveRow($scope, $scope.saveRow)
  }
}

这很接近,但是您使用了appScopeProvider将我们的控制器作用域注入到子网格范围内,实际上您并不需要这样做。相反,我们可以使saveRow通用化,并将其绑定到我们想要的gridApi上。 bind()的第一个参数设置函数的this。我们只需传递网格对象即可,但我们不需要它。bind的第二个参数将是我们想要传递的gridApi。然后在saveRow定义中,我们知道我们将收到正确的API作为第一个参数,然后是rowEntity作为第二个参数。

// Main grid:
$scope.gridOptions.onRegisterApi = function(gridApi) {
  gridApi.rowEdit.on.saveRow($scope, saveRow.bind(gridApi.grid, gridApi));
};

// Subgrids:
onRegisterApi: function(gridApi) {
  gridApi.rowEdit.on.saveRow($scope, saveRow.bind(gridApi.grid, gridApi));
}

// Altered saveRow:
function saveRow(gridApi, rowEntity) {
  var promise = $q.defer();
  gridApi.rowEdit.setSavePromise( rowEntity, promise.promise );

  // fake a delay of 3 seconds whilst the save occurs, return error if gender is "male"
  $interval( function() {
    if (rowEntity.gender === 'male' ){
      promise.reject();
    } else {
      promise.resolve();
    }
  }, 3000, 1);
};

由于您可能会为子网格设置不同的保存功能,最重要的是要在所有子网格上使用onRegisterApi注册“saveRow”事件。

以下是演示上述代码的工作plunker:http://plnkr.co/edit/52mp9C?p=preview


2
如果您使用Angular的$http或$resource,就不需要创建其他的“deferred”对象,只需返回结果即可:
$scope.saveRow = function (order) {
    // with use $http
    var promise = $http.put(ORDER_API + '/' + order._id, order);
    // or with use $resource
    var promise = $resource(ORDER_API + '/:id').save({ id: order._id }, order).$promise;
    $scope.gridApi.rowEdit.setSavePromise(order, promise);
    return promise;
  }

1

您的代码中已经创建了一个延迟承诺。正如错误明确指出,您需要返回一个承诺,因此您应该在代码中添加 return deferred.promise;。我认为您还应该从else语句中返回一个承诺,以便无论如何都能得到承诺的解决/拒绝。

代码

$scope.saveRow = function(order) {
    var deferred = $q.defer();
    $scope.gridApi.rowEdit.setSavePromise(order, promise.promise);
    if (order.number) {
        $http.put(ORDER_API + '/' + order._id, order).success(function() {
            deferred.resolve();
        }).error(function() {
            deferred.reject();
        });
    } else {
        deferred.reject();
    }
    return deferred.promise; //this will return promise to caller function.
};

希望这可以帮到您,如果需要任何其他内容,请告诉我。谢谢 :)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接