2013-03-21 5 views
10

Voglio inserire una riga aggiuntiva in linea in una tabella quando il client fa clic sulla riga. I dati non dovrebbero essere precaricati, dal momento che mi aspetto che ci siano al massimo 30 righe, ma dove ogni riga ha dati associati che non sarebbero ragionevoli recuperare in un get.Push righe in una tabella di rendering con ng-repeat in angolare

Il mio approccio finora è quello di usare ng-repeat per iterare la mia collezione e renderizzare una tabella. Quando il cliente preme la riga, il client si aspetta che i dettagli sulla riga vengano mostrati in linea come una riga aggiuntiva sotto la riga premuta.

<tr ng-repeat="court in courts">    
    <td>{{court.name}}</td> 
    <td>{{court.number}}</td> 
    <td>{{court.nrOfPlayers}}</td> 
    <td> 
    <a href ng:click="toggle(court.number)">Details</a> <!-- click toggles extra row with data loaded async --> 
    </td> 
</tr> 
<!-- extra row here --> 

sono riuscito a vedere i dettagli sotto il tavolo con un ng-spettacolo in un modo hacky, ma che non è quello che voglio.

Come si realizza con angular.js? Qual è il modo angolare di fare questo?

Ecco un violino con un esempio stupido campo da squash http://jsfiddle.net/HByEv/

risposta

7

Penso che una possibile soluzione potrebbe essere http://jsfiddle.net/HByEv/2/.

C'è anche un'alternativa per il messaggio "Nessun giocatore" commentato nel violino se si vuole anche eliminare il <tr ng-show="..."></tr> in più.

Edit:

Come sottolineato nei commenti, in AngularJS 1.2+ è ora possibile utilizzare ng-repeat-start e ng-repeat-end per risolvere questo problema.

Josséf Harush fornito un violino: http://jsfiddle.net/3yamebfw/

+1

nella tua soluzione c'è una duplicazione dell'elemento 'tbody'. nell'angolare 1.2+ puoi usare 'ng-repeat-start' e' ng-repeat-end' per evitare questo. Ho aggiornato il tuo violino: http://jsfiddle.net/3yamebfw/ –

+0

@JossefHarush La tua soluzione è attualmente il modo corretto per farlo. Quando è stata fornita questa risposta, 'ng-repeat-start' e' ng-repeat-end' non erano disponibili. Post scriptum La duplicazione 'tbody' è HTML valido. :) –

0

Bene. In effetti, il problema principale con il tuo progetto è che vuoi mostrare migliaia di righe nella stessa tabella. Funzionerà, ma potrebbe essere difficile renderizzare alcuni browser (IE). Per ogni riga, avrai alcuni attacchi e ogni legame aggiungerà osservatori. Dovresti sempre cercare di ridurre al minimo la quantità di rilegatura nella pagina. Ti suggerisco di usare un sistema di impaginazione nel tuo array. Pagination on a list using ng-repeat

Se si vuole veramente fare ciò che si vuole senza prerenderare le righe, è necessario modificare il dom, che non è una buona pratica in angolare quando evitabile. Nel mio caso, posizionerei i dati da qualche altra parte sulla pagina, in una zona statica. Quando ho fatto qualcosa di simile, ho aggiunto un twitter modal di bootstrap nella mia pagina e quando l'utente ha cliccato su "maggiori informazioni" la modale è stata aperta con le informazioni dell'oggetto selezionato.

+0

Sì, naturalmente, hai ragione su questo difetto di progettazione. Stavo solo diventando poco chiaro. Vedi la mia domanda modificata. L'utilizzo di un modal non è purtroppo quello che consideriamo una soluzione pulita per il nostro problema, ma grazie per l'input. – marko

1

Un campione

var app = angular.module('test-app', []); 

app.controller('MyController', function($scope, $rootScope, $timeout){ 

    $scope.copy = { 
     p1: ['c1 p1', 'c1 p2'], 
     p3: ['c3 p1', 'c3 p2', 'c3 p3', 'c3 p4', 'c3 p5'] 
    } 

    $scope.courts = [ 
     { 
      "number": 1, 
      "name": "the best court", 
      "nrOfPlayers": 2 
     }, { 
      "number": 2, 
      "name": "the bad court", 
      "nrOfPlayers": 0 
     }, { 
      "number": 3, 
      "name": "the other court", 
      "nrOfPlayers": 5 
     } 
    ]; 

    $scope.loadPlayers = function(court){ 
     //Implement your logic here 
     //Probably using ajax 
     $timeout(function(){ 
      $scope.players = $scope.copy['p' + court.number] || []; 
     }, Math.random() * 2000); 
    } 

    $scope.shouDetails = function(court){ 
     if(court.nrOfPlayers) { 
      delete $scope.players; 
      $scope.loadPlayers(court); 
     } else { 
      $scope.players = []; 
     } 
    } 

}) 

Demo: Fiddle

+0

Grazie per il codez. Sfortunatamente (il mio male) non ero chiaro su quale fosse il problema. Vedi la mia domanda modificata! – marko

Problemi correlati