最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Not able to save row in Expandable row in Angular UI Grid - Stack Overflow

programmeradmin3浏览0评论

I'm trying to use the row saving feature in bination with the expandable grid. The goal is to be able to save sub-grid rows, independently of the parent row.

$scope.gridOptions = {
  expandableRowTemplate: 'ponents/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();
    });
  }

}
});

The saveRow function is called correctly when I edit a field in the parent row. When I edit a field in the sub-row, the following message appears in the console;
'A promise was not returned when saveRow event was raised, either nobody is listening to event, or event handler did not return a promise'
SaveRow is never called for the expanded sub-row.

I'm trying to use the row saving feature in bination with the expandable grid. The goal is to be able to save sub-grid rows, independently of the parent row.

$scope.gridOptions = {
  expandableRowTemplate: 'ponents/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();
    });
  }

}
});

The saveRow function is called correctly when I edit a field in the parent row. When I edit a field in the sub-row, the following message appears in the console;
'A promise was not returned when saveRow event was raised, either nobody is listening to event, or event handler did not return a promise'
SaveRow is never called for the expanded sub-row.

Share Improve this question asked Mar 29, 2015 at 18:38 Bartol KaruzaBartol Karuza 1381 silver badge6 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 3 +50

You need to register the subgrid APIs. Each grid has its own separate API instance that you use to municate with it:

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

That's close, but you're injecting our controller scope into the subgrid scope with appScopeProvider, which you don't really need to do. Instead, we can make saveRow generic and bind it to the gridApi we want. The first argument of bind() sets the this for the function. We'll just pass in the grid object, but we won't need it. The second argument to bind will be the gridApi we want to pass. Then in the saveRow definition we know we'll receive the right API as the first argument, and then the rowEntity as the second arg.

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

Since you'll probably have a different save function for your subgrids the main thing to remember is to register the "saveRow" event on them all with onRegisterApi

Here's a working plunker demonstrating the code above: http://plnkr.co/edit/52mp9C?p=preview

If you use Angular $http or $resource, you needn't create any other 'deferred' objects, just return result:

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

You already created a deferred promise in you code. As error clearly says you need to return a promise, You should add return deferred.promise; to your code. I think you should also return a promise from else statement in order to get promise resolve/reject anyhow.

Code

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

Hope this could help you, let me know if anything else is required. Thanks. :)

发布评论

评论列表(0)

  1. 暂无评论