2013-08-30 17 views
13

Sto provando a creare un modello per un'applicazione e voglio visualizzare un elenco dinamico con nomi. quindi ho preso questo codice per mostrare la lista e aggiungere/rimuovere le righe;Ng-init se la matrice non è stata ancora creata

<table ng-init="page.businessRows = []"> 
<thead> 
    <tr> 
     <th>Company</th> 
     <th>Contact</th> 
     <th>Phone</th> 
    </tr> 
</thead> 
    <tr ng-repeat="row in page.businessRows"> 
     <td> 
      <input type="text" ng-model="row.name" /> 
     </td> 
     <td> 
      <input type="text" ng-model="row.contact" /> 
     </td> 
     <td> 
      <input type="text" ng-model="row.phone" /> 
     </td> 
     <td> 
      <button ng-click="page.businessRows.splice($index,1)"> 
       Remove 
      </button> 
     </td> 
    </tr> 
</table> 
<button class="btn" ng-click="page.businessRows.push({})">addRow</button> 

la cosa, come che quando questo modello è caricato page.busnessRows saranno molto probabilmente caricati con le righe in modo che io voglio cambiare il ng-init per creare solo la matrice vuota se businessRows non viene inizializzato.

Ho provato ng-init="page.businessRows = page.businessRows.length < 1 ? [] : page.businessRows ma non ha funzionato. Come intendo fare le condizioni nelle espressioni jsangular?

Tutti apprezzati. Grazie in anticipo

risposta

24

È possibile fare questo, invece:

<table ng-init="page.businessRows = page.businessRows || []"> 

Aggiornamento

guardo il codice parser di AngularJS e si noti che la versione 1.2 (attualmente RC) supporta espressione ternaria. Quindi, se si utilizza AngularJS 1.2, questo funziona anche (anche se più dettagliato rispetto al codice di cui sopra):

<table ng-init="page.businessRows = page.businessRows == null ? [] : page.businessRows"> 

Vedi demo qui.

Tuttavia, il codice originale non potrebbe funzionare se page.businessRows è null, perché il parser non riuscirà a risolvere il riferimento length proprietà di null. Quindi stai attento.

+1

Questo risolve il problema che ha chiesto. Ma non penso che risolva il problema più grande di provare ad usare View come controller. –

+0

Vedo il tuo punto. Anch'io, raramente, se mai, uso ng-init. Detto questo, non posso parlare per tutti e per i loro bisogni. Dopo tutto, la direttiva è lì e se qualcuno pensa che aiuti a risolvere il loro problema, fa bene a loro. –

3

Non penso che ng-init valuterà correttamente le istruzioni condizionali. Ma puoi rifattorizzare la condizione in una funzione controller e chiamare la funzione da ng-init.

<table ng-init="initializeBusinessRows(page.businessRows)"> 

Basta inserire la valutazione condizionata nella funzione nell'ambito del controller.

1

Penso che tu stia cercando di risolvere il problema sbagliato.

Il problema è che si sta verificando un'azione prima che i dati siano caricati o pronti. Un problema secondario è che stai usando un'espressione in un ng-click in cui dovrebbe essere una funzione di ambito o una funzione di controller.

Quindi ...

  1. disabilitare questa pulsante se il modulo non è pronto.
  2. Utilizzare il controller per controllare queste interazioni.

Quindi, ecco un esempio del controller. Il timeout $ è stato aggiunto per simulare un carico di dati ritardato nella variabile $ scope.page.

app.controller('MyCtrl', function($scope, $timeout, $window) { 
    //Timeout to simulate the asynchronous load 
    //of the page object on the $scope 
    $timeout(function(){ 
    $scope.page = { 
     businessRows: [] 
    }; 
    }, 2000); 


    //scope method to add a row. 
    $scope.addRow = function(){ 
    //for safety's sake, check to see if the businessRows array is there. 
    if($scope.page && angular.isArray($scope.page.businessRows)) { 
     $scope.page.businessRows.push({}); 
    } 
    }; 

    //scope method to remove a row 
    $scope.removeRow = function(index, row) { 
    if($window.confirm('Are you sure you want to delete this row?')) { 
     $scope.page.businessRows.splice(index, 1); 
    } 
    }; 
}); 

...e la visualizzazione HTML (notare il ng-disabili e l'ng clic) (e la mancanza di ng-init):

<div ng-controller="MyCtrl"> 
    <table> 
     <thead> 
     <tr> 
      <th>Company</th> 
      <th>Contact</th> 
      <th>Phone</th> 
     </tr> 
     </thead> 
     <tbody> 
     <tr ng-repeat="row in page.businessRows"> 
      <td> 
       <input type="text" ng-model="row.name" /> 
      </td> 
      <td> 
       <input type="text" ng-model="row.contact" /> 
      </td> 
      <td> 
       <input type="text" ng-model="row.phone" /> 
      </td> 
      <td> 
       <button ng-click="removeRow($index, row)"> 
        Remove 
       </button> 
      </td> 
     </tr> 
     </tbody> 
    </table> 
    <button class="btn" ng-disabled="!page" ng-click="addRow()">addRow</button> 
    </div> 

Inoltre, here's the obligatory Plunker for you to see this in action.

+0

... allo stesso modo probabilmente vorrai che il tuo controller configuri un metodo "removeRow (row)". Lo aggiungerò molto velocemente. –

Problemi correlati