71 votes

Comment puis-je faire récursive modèles dans AngularJS lors de l'utilisation d'objets imbriqués?

Je suis en train de construire dynamiquement un formulaire à partir d'un JSON ojbect, qui contient des groupes d'éléments de formulaire:

  $scope.formData = [
  {label:'First Name', type:'text', required:'true'},
  {label:'Last Name', type:'text', required:'true'},
  {label:'Coffee Preference', type:'dropdown', options: ["HiTest", "Dunkin", "Decaf"]},
  {label: 'Address', type:'group', "Fields":[
      {label:'Street1', type:'text', required:'true'},
      {label:'Street2', type:'text', required:'true'},
      {label:'State', type:'dropdown',  options: ["California", "New York", "Florida"]}
    ]},
  ];

J'ai été en utilisant ng-commutateur de blocs, mais il devient intenable avec les éléments imbriqués, comme dans l'Adresse de l'objet ci-dessus.

Voici le violon: http://jsfiddle.net/hairgamiMaster/dZ4Rg/

Toutes les idées sur la meilleure façon d'aborder cette imbriquée problème? Merci beaucoup!

123voto

jpmorin Points 2345

Je pense que cela pourrait vous aider. C'est à partir de la réponse que j'ai trouvé sur un Groupe Google sur les éléments dans un arbre.

La suggestion est de Brendan Owen: http://jsfiddle.net/brendanowen/uXbn6/8/

<script type="text/ng-template" id="field_renderer.html">
    {{data.label}}
    <ul>
        <li ng-repeat="field in data.fields" ng-include="'field_renderer.html'"></li>
    </ul>
</script>

<ul ng-controller="NestedFormCtrl">
    <li ng-repeat="field in formData" ng-include="'field_renderer.html'"></li>
</ul>

La solution proposée consiste à utiliser un modèle qui utilise le ng-include pour appeler lui-même si l'élément en cours a des enfants.

Dans votre cas, je voudrais essayer de créer un modèle avec le ng-commutateur de la directive (un cas par type d'étiquette comme vous l'avez fait) et ajouter le ng-inclure à la fin si il y a un enfant étiquettes.

10voto

Dexter Legaspi Points 404

En combinant ce que @jpmorin et @Ketan suggéré (léger changement sur @jpmorin de réponse car il ne fait pas son travail)...il y a un ng-if pour éviter la "feuille d'enfants" à partir de la génération inutiles ng-repeat directives:

<script type="text/ng-template" id="field_renderer.html">
  {{field.label}}
  <ul ng-if="field.Fields">
      <li ng-repeat="field in field.Fields" 
         ng-include="'field_renderer.html'">
      </li>
  </ul>
</script>
<ul>
  <li ng-repeat="field in formData" ng-include="'field_renderer.html'"></li>
</ul>

voici la version de travail en Plunker

1voto

Ketan Points 2871

Pouvez envisager d'utiliser ng-commutateur pour vérifier la disponibilité de Champs de propriété. Si oui, alors utiliser un modèle différent pour cette condition. Ce modèle aurait une ng-repeat sur le tableau de Champs.

1voto

Jens Points 910

Je sais que c'est une vieille question, mais pour d'autres qui pourraient venir par ici, mais une recherche, j'ai pensé que je laisserais une solution qui pour moi est un peu plus soignée.

Il s'appuie sur la même idée, mais plutôt que d'avoir à stocker un modèle à l'intérieur de la cache de template etc. Je voulais un plus "propre" solution, j'ai donc fini par créer https://github.com/dotJEM/angular-tree

Il est assez simple à utiliser:

<ul dx-start-with="rootNode">
  <li ng-repeat="node in $dxPrior.nodes">
    {{ node.name }}
    <ul dx-connect="node"/>
  </li>
</ul>

0voto

Juste envie de prolonger jpmorin post en cas de propriété en fonction de la structure:

 JSON:
{
          "id": 203,
          "question_text_id": 1,
          "yes": {
            "question_text_id": 25,
            "yes": {
              "question_text_id": 26
            }
          },
          "no": {
            "question_text_id": 4
          }
        }

Comme vous pouvez le voir objet json ici ne contient pas de structure de tableau.

HTML

<div>
    <script type="text/ng-template" id="tree_item_renderer.html">
        <span>{{key}} {{value}}</span>
        <ul>
            <li ng-repeat="(key,value) in value.yes" ng-include="'tree_item_renderer.html'"></li>
            <li ng-repeat="(key,value) in value.no" ng-include="'tree_item_renderer.html'"></li>
        </ul>
    </script>

    <ul>
        <li ng-repeat="(key,value) in symptomeItems" ng-include="'tree_item_renderer.html'"></li>
    </ul>
</div>

Cependant, vous pouvez effectuer une itération sur elle.

Angulaire de la documentation pour les ng-repeat sur les propriétés ici

Et un certain nombre de lignes de la mise en œuvre ici

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X