2016-04-11 12 views
6

Sto cercando di creare una sorta di gridview generico utilizzando AngularJS 1.5 e i suoi componenti. Una versione (pseudocodice) di quello che ho cominciato ad andare in questo momento:Angolare 1.5: caricare dinamicamente un componente

// inside <my-grid-component data="data" metadata="metadata"> 
<div ng-repeat="item in $ctrl.data"> 
    <my-row-component item="item" metadata="$ctrl.metadata"></my-row-component> 
</div 

// inside <my-row-component item="item" metadata="metadata"> 
<div ng-repeat="column in $ctrl.metadata.columns"> 
    <my-cell-component value="$ctrl.item[column]"></my-cell-component> 
</div> 

Ora <my-cell-component> potrebbe avere un po 'di base ng-switch dichiarazione che gestisce i casi evidenti, come se il valore è un testo o un'immagine o qualcosa del genere, ma dal momento che questo sarà usato da molte persone e su molti progetti, è possibile che qualcuno voglia fare qualcosa di particolare e/o altamente specifico all'interno di una cella. Lo potrebbe solo ammontare <my-cell-component> con più ng-switch es, ma poi stanno facendo scherzi con il codice della struttura di base che danneggia la manutenibilità.

Quindi, idealmente, vorrei creare qualcosa in cui uno sviluppatore possa facoltativamente fornire il proprio modello personalizzato per un campo specifico nei metadati, ad es. metadata.columns[3].customCellComponentName = 'some-custom-template'; Poi <my-row-component> sarebbe simile a questa:

<div ng-repeat="column in $ctrl.metadata.columns"> 
    <div ng-if="!column.isCustomCellComponent"> 
     <my-cell-component value="$ctrl.item[column]"></my-cell-component> 
    </div> 
    <div ng-if="column.isCustomCellComponent"> 
??? --> <column.customCellComponentName value="$ctrl.item[column]"></column.customCellComponentName> 
    </div> 
</div> 

Il progetto mette automaticamente tutti i modelli a $ templateCache, così risolvendo il modello non dovrebbe essere un problema, ma a parte questo, la linea tracciata con il "?? ?" ovviamente non funziona Dimostra ciò che mi piacerebbe ottenere, ma non ho idea di come effettivamente fare qualcosa di simile. Ho esaminato la modalità di esclusione, ng-include e altre soluzioni, ma nessuna sembra offrire l'opzione per caricare dinamicamente un modello AND modello-associa alcuni dati ad esso.

Tutte le idee sono benvenute. Mi piacerebbe rimanere il più lontano possibile da direttive troppo complesse. Mentre ti permettono di fare molte cose, nella mia esperienza sono anche un incubo di debugging e manutenibilità.

Grazie.

risposta

0

È possibile creare una direttiva per il proprio <my-cell-component> in modo che accetti uno templateUrl oppure determini il templateUrl e lo utilizzi. Lasciate che vi faccia un esempio per questi ultimi,

angular.module('myApp') 
    .directive('myCellComponent', ['CELL_TYPE', function (CELL_TYPE) { 
     return { 
      restrict: 'E', 
      scope:{ 
       cellType: '=' 
      }, 
      template: '<div ng-include="templateUrl"></div>', 
      link: function (scope) { 
       function setTemplate(cellType) { 
        scope.templateUrl = CELL_TYPE[cellType.value].templateUrl; 
        // or figure out some other way to determine templateUrl 
       } 
       scope.$watch(function() { 
        return scope.cellType; 
       }, function (newVal) { 
        if(newVal) { 
         setTemplate(scope.cellType); 
        } 
       }); 
      } 
     }; 
}]); 

Così, abbiamo modello della direttiva avendo un ng-include che utilizza il templateUrl determinato sulla base di alcune costanti, dicono CELL_TYPE.

Ora hai una direttiva che carica dinamicamente il modello in base ai tuoi attributi!

È possibile (ovviamente) eliminare $watch se la modifica dinamica dello templateUrl non è applicabile al caso d'uso.

Problemi correlati