问题
In ng-grid
, I used to use beforeSelectionChange
in the following way:
When the user selects a row, an ajax call is performed. While the ajax call is happenning I set $scope.doingAjaxCall = true
, and to prevent the user from changing the selection, I had this in the grid definition:
beforeSelectionChange: function () {
return !($scope.doingAjaxCall);
},
which locks/freezes the selection if the ajax call is happenning.
Now, in ui-grid
(aka ng-grid 3), I don't know whats the equivalent for afterSelectionChange
.
In this section of the documentation:
http://ui-grid.info/docs/#/api/ui.grid.selection.api:PublicApi
I see two events:
rowSelectionChanges
rowSelectionChangedBatch
.
These seem to be the equivalent of the old afterSelectionChange
And in this section of the documentation:
http://ui-grid.info/docs/#/api/ui.grid.selection.service:uiGridSelectionService
I see these two methods that seem to be related to the need:
raiseSelectionEvent(grid, changedRows, event)
decideRaiseSelectionEvent(grid, row, changedRows, event)
But I don't understand how to use them
Important note:
I'm using multiSelect: false
(ie: only one row can be selected)
回答1:
This is a bit of a hack, but it'll get the job done until you find a better solution. Here's a working plunker.
I assume you use rowSelectionChanged
to perform the AJAX call and toggle doingAjaxCall
.
gridApi.selection.on.rowSelectionChanged($scope, function(row) {
$log.log('Row ' + row.entity.id + ' selected: ' + row.isSelected);
$log.log(' Simulating ajax call...');
$scope.doingAjaxCall = true;
$timeout(function() {
$log.log(' ...done with ajax call');
$scope.doingAjaxCall = false;
}, 2000);
});
Then, modify the template that ui-grid uses for the select buttons.
$templateCache.put('ui-grid/selectionRowHeaderButtons',
'<div ' +
' class="ui-grid-selection-row-header-buttons ui-grid-icon-ok" ' +
' ng-class="{\'ui-grid-row-selected\': row.isSelected}" ' +
' ng-click="grid.appScope.clickConditions() && selectButtonClick(row, $event)"> ' + // Modified template here
' ' +
'</div>'
);
This way, $scope.clickConditions()
is evaluated before the actual click logic is called. If it's falsy, then selectButtonClick
, which handles the internal selection logic, is never called.
$scope.clickConditions = function() {
// Check for any other conditions you need
return !$scope.doingAjaxCall;
};
As I mentioned, this is very hacky! There are better ways to overwrite the templates (e.g. ui-grid/selectionRowHeaderButtons
), when overwriting templates you'll have to check the logic when updating, you should probably let the user know that something is happening visually when the AJAX call is performed, etc.
A better solution would be to fork the repo and add your own beforeSelectionChange
logic (probably starting here). But it seems like you haven't gotten much help elsewhere, so hope the this gets you started at least!
回答2:
ui-grid provides the tools to do this, I'm not sure there's a "ui-grid" way, but there are definitely ways to do it that are compatible.
Based on your description I'm assuming you are only allowing single selection, because if you allowed multiple selection they could keep adding selections and you'd run the ajax in the background. So I assume you're setting multiSelect: false
per http://ui-grid.info/docs/#/tutorial/210_selection
I can see two ways to get the result:
If the user tries to select a row whilst an ajax call is running, set the selection back to where it was. This means you'd have to listen to the selectionChanged and selectionChangedBatch events, keep track of the selection that you want, and keep track of when an ajax call was in progress.
Use an
isRowSelectable
function that doesn't let any row be selected if an ajax call is running. The function itself is similar to what you used to have with ng-grid i.e.return !$scope.doingAjaxCall
. The difference is you need to callnotifyDataChange
whenever you change the value of$scope.doingAjaxCall
. From memory making a row not selectable by the user will still allow it to be selected in code - so this won't change that the row is selected.
I'd probably go with the second option.
Adding information as requested: isRowSelectable
is in the tutorial as noted above (there's an example of it working). The only trick is that I have a feeling it's only re-evaluated on specific events, so it may not just automatically remove the select from each item when you change the doingAjaxCall
variable. Hence I recommended calling notifyDataChange
, which is also in the tutorial.
I'd suggest you have a go at it in a plunker, and then if you have difficulty I can look and provide advice. I don't have the time right now to write it from scratch.
来源:https://stackoverflow.com/questions/32101026/whats-the-equivalent-for-ng-grids-beforeselectionchange-in-ui-grid