J'ai passé un peu de temps à rassembler les morceaux de ce pour ng-grille 2.x. J'ai encore un problème avec le fait d'avoir à cliquer deux fois pour modifier une ligne, mais je pense que c'est un bootstrap question, pas une ngGrid problème, il ne se passe pas dans mon exemple de code (qui n'ont pas de bootstrap encore).
J'ai également mis en œuvre une logique similaire dans un tutoriel pour l'interface utilisateur de la grille 3.0, qui est encore en version bêta, mais deviendra bientôt la version préférée. Cela peut être trouvé à: http://technpol.wordpress.com/2014/08/23/upgrading-to-ng-grid-3-0-ui-grid/et fournit un beaucoup plus facile et plus propre api pour cette fonctionnalité.
Pour la 2.x version, pour illustrer tous les bits, j'ai créé une course plunker qui a une grille modifiable à la fois avec une liste déroulante et un champ de saisie, utilise le ngBlur directive, et utilise un $timeout d'éviter de dupliquer les enregistre sur la mise à jour: http://plnkr.co/edit/VABAEu?p=preview
Les bases de ce code sont:
var app = angular.module('plunker', ["ngGrid"]);
app.controller('MainCtrl', function($scope, $timeout, StatusesConstant) {
$scope.statuses = StatusesConstant;
$scope.cellInputEditableTemplate = '<input ng-class="\'colt\' + col.index" ng-input="COL_FIELD" ng-model="COL_FIELD" ng-blur="updateEntity(row)" />';
$scope.cellSelectEditableTemplate = '<select ng-class="\'colt\' + col.index" ng-input="COL_FIELD" ng-model="COL_FIELD" ng-options="id as name for (id, name) in statuses" ng-blur="updateEntity(row)" />';
$scope.list = [
{ name: 'Fred', age: 45, status: 1 },
{ name: 'Julie', age: 29, status: 2 },
{ name: 'John', age: 67, status: 1 }
];
$scope.gridOptions = {
data: 'list',
enableRowSelection: false,
enableCellEditOnFocus: true,
multiSelect: false,
columnDefs: [
{ field: 'name', displayName: 'Name', enableCellEditOnFocus: true,
editableCellTemplate: $scope.cellInputEditableTemplate },
{ field: 'age', displayName: 'Age', enableCellEdit: false },
{ field: 'status', displayName: 'Status', enableCellEditOnFocus: true,
editableCellTemplate: $scope.cellSelectEditableTemplate,
cellFilter: 'mapStatus'}
]
};
$scope.updateEntity = function(row) {
if(!$scope.save) {
$scope.save = { promise: null, pending: false, row: null };
}
$scope.save.row = row.rowIndex;
if(!$scope.save.pending) {
$scope.save.pending = true;
$scope.save.promise = $timeout(function(){
// $scope.list[$scope.save.row].$update();
console.log("Here you'd save your record to the server, we're updating row: "
+ $scope.save.row + " to be: "
+ $scope.list[$scope.save.row].name + ","
+ $scope.list[$scope.save.row].age + ","
+ $scope.list[$scope.save.row].status);
$scope.save.pending = false;
}, 500);
}
};
})
.directive('ngBlur', function () {
return function (scope, elem, attrs) {
elem.bind('blur', function () {
scope.$apply(attrs.ngBlur);
});
};
})
.filter('mapStatus', function( StatusesConstant ) {
return function(input) {
if (StatusesConstant[input]) {
return StatusesConstant[input];
} else {
return 'unknown';
}
};
})
.factory( 'StatusesConstant', function() {
return {
1: 'active',
2: 'inactive'
};
});
Lorsque vous exécutez cette plunker, et le perdre de vue l'objectif de feux, vous devriez voir sur la console de la mise à jour de déclenchement de tir.
J'ai aussi inclus un fichier README.md dans le plunker avec quelques pensées sur des choses qui m'a donné de la difficulté, de les reproduire ici.
La fonctionnalité ici, c'est que j'ai une liste de gens, ces gens
les noms, âges et de statuts. En ligne avec ce que nous pourrions faire dans un vrai
app, l'état est un code, et nous voulons montrer à la décoder. En conséquence
nous avons un état de la liste des codes (qui pourrait, dans une application réelle proviennent de la base de données),
et nous avons un filtre à la carte le code pour le décoder.
Ce que nous voulons sont deux choses. Nous aimerions être en mesure de modifier le nom dans
une zone de saisie, et de modifier le statut dans une liste déroulante.
Commentaires sur des choses que j'ai appris sur ce plunk.
Au gridOptions niveau, il y a deux enableCellEditOnFocus et
enableCellEdit. Ne pas permettre à la fois, vous devez choisir. onFocus moyens
seul clic, CellEdit à-dire le double clic. Si vous activez les deux alors
vous obtenez un comportement inattendu sur les bits de votre grille, vous ne voulez pas
pour être modifiable
Au columnDefs niveau, vous avez les mêmes options. Mais cette fois, vous
besoin de définir à la fois CellEdit et onFocus, et vous devez définir cellEdit à
faux sur les cellules que vous ne voulez pas éditer - ce n'est pas la valeur par défaut
-
La documentation dit que votre cellule modifiable modèle peut être:
<input ng-classe="'colt' + col.l'indice de" ng-entrée="COL_FIELD" />
en fait il doit être:
<input ng-classe="'colt' + col.l'indice de" ng-entrée="COL_FIELD" ng-model="COL_FIELD" />
Pour déclencher un enregistrement de l'événement quand nous perdons, nous avons créé un flou de la directive,
la logique que j'ai trouvé dans stackoverflow: AngularJS et ng-grille - sauvegarde automatique des données vers le serveur après qu'une cellule a été modifiée
Cela signifie aussi changer chaque cellule modifiable modèle d'appeler ng-flou, qui
vous pouvez voir à la fin de la cellule modifiable modèle
Nous obtenons deux flou événements lorsque nous quittons le terrain (au moins dans google Chrome), de sorte que nous
utilisez une minuterie de sorte que seulement l'un d'eux est traité. Moche, mais ça fonctionne.
J'ai également créé un blog qui n'est plus approfondie de la soluce de ce code: http://technpol.wordpress.com/2013/12/06/editable-nggrid-with-both-dropdowns-and-selects/