2016-04-11 26 views
6

Ich versuche, eine Art generische Gridview mit AngularJS 1.5 und seinen Komponenten zu erstellen. A (Pseudo-Code) Version von dem, was ich habe jetzt in Gang gekommen:Angular 1.5: Komponente dynamisch laden

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

Jetzt konnte <my-cell-component> haben einige grundlegende ng-switch Aussage, dass die offensichtlichen Fälle behandelt, wie wenn der Wert Text oder ein Bild oder so etwas, aber da Dies wird von vielen Leuten benutzt und bei vielen Projekten ist es möglich, dass jemand etwas Fantastisches und/oder hoch Spezifisches in einer Zelle machen möchte. Sie könnte nur <my-cell-component> mit mehr ng-switch es amendieren, aber dann sind sie mit Basis-Framework-Code Unordnung, die Wartbarkeit verletzt.

Also, idealerweise würde ich etwas machen wollen, wo ein Entwickler kann optional seine eigene benutzerdefinierte Vorlage für ein bestimmtes Feld in den Metadaten, z. metadata.columns[3].customCellComponentName = 'some-custom-template'; Dann <my-row-component> würde wie folgt aussehen:

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

Das Projekt stellt automatisch alle Vorlagen in $ templateCache, so dass die Vorlage Lösung sollte kein Problem sein, aber anders als das, die markierte Linie mit der „?? " offensichtlich funktioniert nicht. Es zeigt, was ich gerne erreichen würde, aber ich habe keine Ahnung, wie ich so etwas tatsächlich machen soll. Ich habe mich mit der Einbettung, ng-include und anderen Lösungen beschäftigt, aber keine scheint die Möglichkeit zu bieten, ein Template dynamisch zu laden und einige Daten daran zu binden.

Alle und alle Ideen sehr willkommen. Ich möchte so weit wie möglich von zu komplexen Richtlinien abweichen. Während sie Ihnen erlauben, viele Dinge zu tun, sind sie meiner Erfahrung nach auch ein Albtraum für die Fehlersuche und Wartung.

Danke.

Antwort

0

Sie können eine Richtlinie für Ihre <my-cell-component> so erstellen, dass sie entweder eine templateUrl annimmt oder es bestimmt die templateUrl und verwendet sie. Lassen Sie mich Ihnen ein Beispiel für die letztere,

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); 
        } 
       }); 
      } 
     }; 
}]); 

So haben wir die Richtlinie der Vorlage ein ng-include mit bekommen, das die templateUrl auf der Grundlage einiger Konstanten bestimmt verwendet, sagt CELL_TYPE.

Jetzt haben Sie eine Direktive, die dynamisch ihre Vorlage basierend auf Ihren Attributen lädt!

Sie können (offensichtlich) $watch loswerden, wenn die templateUrl dynamisch geändert wird, ist nicht auf Ihren Anwendungsfall anwendbar.

Verwandte Themen