2013-04-22 21 views
10

Sto tentando di visualizzare dinamicamente uno dei diversi modelli all'interno di una direttiva ng-repeat, in base all'elemento corrente.Visualizzazione dinamica del modello nella direttiva ng-repeat in AngularJS?

miei dati JSON è simile al seguente:

data: { 
    groups: [ 
     { 
      name: "Group 1",     
      sections: [ 
       { name: "Section A" }, 
       { name: "Section B" } 
      ] 
     }, 
     { 
      name: "Group 2",     
      sections: [ 
       { name: "Section A" }, 
       { name: "Section B" } 
      ] 
     } 
    ] 
} 

Il mio obiettivo è quello di rendere l'albero dei dati in modo dinamico, con ogni gruppo che contiene più sezioni. I gruppi avranno tutti lo stesso modello, ma ogni sezione dovrebbe avere il proprio modello, basato sul campo del nome.

Supponendo HTML livello superiore è:

<div ng-repeat="group in groups"> 
    {{ group.name }} 
    <div ng-repeat="section in sections"> 
     <!-- Dynamic section template used --> 
    </div> 
</div> 

Idealmente, ogni sezione sarebbe anche necessario avere i propri dati con ambito e controllore associato con esso. Ho avuto la fortuna di costruire questo tipo di sistema con Knockout ma sto cercando di capire il modo angolare di fare le cose.

+0

Sembra un buon caso per una direttiva. – lucuma

+0

Lucuma, puoi commentare di più? Ho pensato di utilizzare anche le direttive, ma non sono sicuro del livello ideale di granularità. Dovrei costruire una direttiva che faccia solo la selezione dei template, o ogni "sezione" debba avere la propria direttiva? –

+0

Penso che dipenda da come lo vuoi fare. È possibile creare una direttiva per eseguirla tutte (passare nell'array dei gruppi) e/o è possibile creare un'altra direttiva chiamata all'interno della direttiva dei gruppi per gestire le sezioni. Il vantaggio di una direttiva è che ottengono il loro scopo. Fornirò un piccolo esempio. – lucuma

risposta

31

Si potrebbe fare qualcosa di simile:

<div ng-repeat="group in groups"> 
    {{ group.name }} 
    <div ng-repeat="section in sections" ng-include="getIncludeFile(section)"> 
     <!-- Dynamic section template used --> 
    </div> 
</div> 

Poi nel controller:

$scope.getIncludeFile = function(section) { 
    // Make this more dynamic, but you get the idea 
    switch (section) { 
     case "Section A": 
      return 'partials/sectiona.html'; 
     case "Section B": 
      return 'partials/sectionb.html'; 
    } 
} 

Allora la vostra sectiona.html potrebbe assomigliare a questo (per avere un controller specifico per quel file):

+0

Questo è il metodo più diretto per i miei usi in questo momento. Se le mie esigenze si complicheranno, potrei adottare l'approccio della direttiva. –

+0

Funziona come un fascino, una soluzione eccellente! – chromaloop

+0

e se volessi trasformare gli elementi di JSON in una lista di link che si dirigerebbero verso una nuova pagina ...Tutte queste pagine seguiranno lo stesso modello con proprietà uniche come un post-tipo .... Ma non ho bisogno di un db o di un amministratore. Serve solo una nuova pagina per ogni elemento di dati con lo stesso modello di visualizzazione. – Omar

4

Nel mese scorso è stato effettuato il check-in in modo angolare per il supporto di modelli dinamici in una direttiva tuttavia non sono riuscito a trovare molte informazioni riguardo al suo utilizzo. Ecco il riferimento. https://github.com/angular/angular.js/pull/1849

Anche se questo utilizza ancora il lo stesso nginclude tutto è incapsulato in due direttive:

Demo: http://plnkr.co/edit/4DIlHMNlHQ8Wm9XHNycH?p=preview

HTML:

<groups-control groupdata="groups"></groups-control> 

Controller:

app.controller('MainCtrl', function($scope) { 
    $scope.name = 'World'; 
    var json = {data: { 
    groups: [ 
     { 
      name: "Group 1",     
      sections: [ 
       { name: "Section A" }, 
       { name: "Section B" } 
      ] 
     }, 
     { 
      name: "Group 2",     
      sections: [ 
       { name: "Section A" }, 
       { name: "Section B" } 
      ] 
     } 
    ] 
    }}; 
    $scope.groups = json.data.groups; 

}); 

Direttiva divisa in due:

app.directive('groupsControl', function(){ 
    return { 
     restrict: 'E', 

     replace: true, 
     transclude: false, 
     scope: { items:'=groupdata'}, 

     template: '<div ng-repeat="group in items">' + 
        '{{ group.name }}' + 
        '<section-control sections="group.sections" />'+ 

       '</div>', 
     // The linking function will add behavior to the template 
     link: function(scope, element, attrs) { 


     } 
    } 
    }).directive('sectionControl', function(){ 
    return { 
     restrict: 'E', 

     replace: true, 
     transclude: false, 
     scope: { items:'=sections'}, 

     template: '<div ng-repeat="section in items" ng-include="getIncludeFile(section)">'+ 
       '</div>', 

     link: function(scope, element, attrs) { 
     scope.getIncludeFile = function(section) { 
      return section.name.toLowerCase().replace('section ','') + ".html"; 
     } 

     } 
    } 
    }); 

Mi piacerebbe davvero vedere qualcuno inviare una risposta utilizzando una funzione per il templateUrl basato su alcuni dati di ambito.

Problemi correlati