web-dev-qa-db-fra.com

Ng-init si le tableau n'a pas encore été créé

J'essaie de créer un modèle pour une application et je souhaite afficher une liste dynamique avec des noms. donc j'ai eu ce code pour afficher la liste et ajouter/supprimer des lignes;

<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>

quand ce modèle est chargé, page.busnessRows sera probablement chargé avec des lignes. Par conséquent, je souhaite modifier le ng-init afin de ne créer le tableau vide que si businessRows n'est pas initialisé.

J'ai essayé ng-init="page.businessRows = page.businessRows.length < 1 ? [] : page.businessRows mais cela n'a pas fonctionné. Comment ai-je l'intention de faire des conditions dans des expressions rectangulaires?

Toute aide appréciée. Merci d'avance

13
oBusk

Vous pouvez le faire à la place:

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

Mettre à jour 

Je regarde le code de l'analyseur de AngularJS et remarque que la version 1.2 (actuellement RC) supporte l'expression ternaire. Donc si vous utilisez AngularJS 1.2, cela fonctionnera aussi (bien que plus verbeux que le code ci-dessus):

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

Voir demo ici.

Cependant, votre code d'origine pourrait ne pas fonctionner si page.businessRows est null, car l'analyseur ne parviendra pas à déréférencer la propriété length de null. Alors soyez prudent là-bas.

24
Buu Nguyen

Je ne pense pas que le ng-init évaluera correctement les instructions conditionnelles. Mais vous pouvez reformuler la condition dans une fonction du contrôleur et appeler la fonction depuis ng-init 

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

Il suffit de mettre votre évaluation conditionnelle dans la fonction du périmètre du contrôleur.

3
BoxerBucks

Je pense que vous essayez de résoudre le mauvais problème.

Le problème est que vous autorisez une action avant que les données ne soient chargées ou prêtes. Un problème secondaire est que vous utilisez une expression dans un clic-ng où une fonction de portée ou une fonction de contrôleur devrait être.

Alors...

  1. Désactivez ce bouton si le formulaire n'est pas prêt.
  2. Utilisez votre contrôleur pour contrôler ces interactions.

Alors, voici un exemple du contrôleur. Le timeout $ a été ajouté pour simuler un chargement retardé de données dans votre variable $ 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);
    }
  };
});

... et la vue HTML (notez ng-disabled et ng-click) (et l'absence de 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>

En outre, voici le Plunker obligatoire pour que vous puissiez voir cela en action .

1
Ben Lesh