web-dev-qa-db-fra.com

Angular UI Grid click row

J'ai une liste d'éléments dans un Angular UI Grid . Lorsque je clique sur une ligne, je souhaite être redirigé vers une autre page. (En d'autres termes, chaque ligne de la grille sera un lien.)

J'imagine que cela doit être un désir très commun, bien que je n'ai pas vraiment vu de documentation sur la façon de le faire. Quelle est la bonne façon d'y parvenir?

15
Jason Swett

J'ai moi-même trouvé la réponse. Voici mon contrôleur (ES6):

'use strict';

class TrackingRecordsCtrl {
  constructor($scope) {
    // The content of this template is included
    // separately 
    $scope.gridOptions = {
      rowTemplate: 'app/components/tracking-record/grid-row.html',
    };

    // This function is referenced from the row's template.
    // I'm just console.logging the row but you can of
    // course do anything you want with it.
    $scope.gridRowClick = row => {
      console.log(row);
      // or maybe $location.path(row.url)?
    };

    $scope.gridOptions.data = {
      // This of course can't just be an empty object.
      // Chances are you already have something defined
      // for gridOptions.data.
    };
  }
}

TrackingRecordsCtrl.$inject = ['$scope'];

export default TrackingRecordsCtrl;

Et voici mon modèle de ligne (Jade):

.ui-grid-cell(
  ng-repeat='(colRenderIndex, col) in colContainer.renderedColumns track by col.colDef.name'
  ng-class="{ 'ui-grid-row-header-cell': col.isRowHeader  }"
  ui-grid-cell=''
  ng-click='grid.appScope.gridRowClick(row)'
)

Et en bonus, voici ma feuille de style (SCSS). J'ai pensé qu'il serait judicieux de mettre en surbrillance la ligne sous le curseur et d'utiliser un curseur pointer pour préciser que les lignes sont cliquables.

.ui-grid-row {
  cursor: pointer;

  &:hover .ui-grid-cell {
    background-color: #CCC;
  }
}
20
Jason Swett

Voici la solution que j'ai utilisée. https://stackoverflow.com/a/32815458/24526

        yourCtrl.gridOptions = {
        enableFiltering: true,
        enableHiding : false,
        enableSorting: true,
        appScopeProvider : yourCtrl,
        rowTemplate: '<div ng-click="grid.appScope.doSomething(row)" ng-repeat="(colRenderIndex, col) in colContainer.renderedColumns track by col.uid" class="ui-grid-cell" ng-class="col.colIndex()" ui-grid-cell></div>',
    };

    yourCtrl.doSomething = function(row) {
        alert("lala");
    }
15
KuN

La question telle que je la comprends: cliquer sur une ligne dans une Angular UI devrait entraîner la navigation vers une page connexe (c'est-à-dire que la ligne doit se comporter comme un lien). Par exemple, une liste de contacts sont affichés dans la grille, et cliquer sur une ligne vous amène à une page de détails de contact.

Félicitations au PO pour avoir répondu à sa propre question de manière innovante. Cependant, je préfère cela réponse car il ne nécessite pas la création d'un modèle de ligne personnalisé. Je l'ai étoffé un peu plus, car le PO ne semblait pas satisfait de l'exemple de Kathir.

Tout d'abord, sachez que le code suivant configure une fonction d'écoute chaque fois que la propriété row.isSelected change:

gridApi.selection.on.rowSelectionChanged($scope,function(row){
        //Do something when a row is selected
      });

C'est à dire. chaque fois qu'une ligne est cliquée, cette fonction sera appelée. Notez le paramètre row passé à la fonction qui peut être utilisée pour accéder à l'entité que la ligne représente. Par exemple, si une ligne représente une entité de contact, vous pouvez accéder à la propriété contactId de la ligne/entité sélectionnée. L'exemple suivant utilise le service $state Du routeur d'interface utilisateur pour accéder à une page de détails de contact en passant le contactId obtenu à partir de la propriété row.entity:

this.gridOptions.onRegisterApi = function (gridApi) {
                //set gridApi to controller property
                this.gridApi = gridApi;
                gridApi.selection.on.rowSelectionChanged($scope, function (row) {
                    $state.go("contact.details.view", {contactId: row.entity.contactId});
                });
            }

Notez que l'objet $scope Doit être transmis, même si vous utilisez la syntaxe Controller as. Reportez-vous à cette article sur la syntaxe Controller as.

Pour un exemple complet utilisant TypeScript (références de fichier omises par souci de concision):

"use strict"
export class ContactsCtrl {

    title: string;
    contacts: interfaces.IContact[] = [];
    gridAPI: any;
    gridOptions: any = {
        enableFullRowSelection: true,
        enableRowSelection: true,
        multiSelect: false,
        enableRowHeaderSelection: false,
        data: "vm.contacts",
        columnDefs: [
            { field: "contactId", displayName: "Contact ID", width: 100 },
            { field: "name", displayName: "Contact Name" }            ]
    }

    static $inject = ["$scope", "$state"];
    constructor(private $scope : ng.IScope, private $state : ng.ui.IStateService) {
        this.gridOptions.onRegisterApi = function (gridApi) {
            //set gridApi on scope
            this.gridApi = gridApi;
            gridApi.selection.on.rowSelectionChanged($scope, function (row) {
                $state.go("contact.details.view", {contactId: row.entity.contactId});
            });
        }
    }
}
angular.module("app.contacts").controller("ContactsCtrl", contacts.controllers.ContactsCtrl);
}
12
Blake Mumford
  $scope.gridOptions.onRegisterApi = function( gridApi ) {
    $scope.gridApi = gridApi;
       gridApi.selection.on.rowSelectionChanged($scope,function(row){
        var msg = 'row selected ' + row.isSelected;
        //Open your link here.
      });
  };

http://plnkr.co/edit/EO920wsxuqr3YU8931GF?p=preview

4
Kathir