I'm trying to use the row saving feature in combination with the expandable grid. The goal is to be able to save sub-grid rows, independently of the parent row.
我正在尝试将行保存功能与可扩展网格结合使用。目标是能够独立于父行保存子网格行。
$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();
});
}
}
});
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.
当我在父行中编辑字段时,会正确调用saveRow函数。当我在子行中编辑字段时,控制台中会显示以下消息; '当引发saveRow事件时,没有返回一个promise,或者没有人正在侦听事件,或者事件处理程序没有返回一个promise'从未为扩展的子行调用SaveRow。
3 个解决方案
#1
3
You need to register the subgrid APIs. Each grid has its own separate API instance that you use to communicate with it:
您需要注册子网格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)
}
}
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.
这很接近,但是您使用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);
};
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
由于您可能对子网格有不同的保存功能,因此要记住的主要事情是使用onRegisterApi在它们上注册“saveRow”事件
Here's a working plunker demonstrating the code above: http://plnkr.co/edit/52mp9C?p=preview
这是一个展示上述代码的工作人员:http://plnkr.co/edit/52mp9C?p = preview
#2
2
If you use Angular $http or $resource, you needn't create any other 'deferred' objects, just return result:
如果您使用Angular $ http或$ resource,则无需创建任何其他“延迟”对象,只需返回结果:
$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;
}
#3
1
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.
您已在代码中创建了延迟承诺。由于错误清楚地表明您需要返回一个承诺,您应该添加return deferred.promise;你的代码。我认为您还应该从else语句中返回一个承诺,以便无论如何都能得到承诺解决/拒绝。
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. :)
希望这可以帮助你,让我知道是否还需要其他任何东西。谢谢。 :)
#1
3
You need to register the subgrid APIs. Each grid has its own separate API instance that you use to communicate with it:
您需要注册子网格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)
}
}
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.
这很接近,但是您使用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);
};
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
由于您可能对子网格有不同的保存功能,因此要记住的主要事情是使用onRegisterApi在它们上注册“saveRow”事件
Here's a working plunker demonstrating the code above: http://plnkr.co/edit/52mp9C?p=preview
这是一个展示上述代码的工作人员:http://plnkr.co/edit/52mp9C?p = preview
#2
2
If you use Angular $http or $resource, you needn't create any other 'deferred' objects, just return result:
如果您使用Angular $ http或$ resource,则无需创建任何其他“延迟”对象,只需返回结果:
$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;
}
#3
1
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.
您已在代码中创建了延迟承诺。由于错误清楚地表明您需要返回一个承诺,您应该添加return deferred.promise;你的代码。我认为您还应该从else语句中返回一个承诺,以便无论如何都能得到承诺解决/拒绝。
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. :)
希望这可以帮助你,让我知道是否还需要其他任何东西。谢谢。 :)