2016-04-11 2 views
6

Я пытаюсь создать своего рода общий gridview, используя AngularJS 1.5 и его компоненты. A (псевдокод) версия о том, что я получил происходит прямо сейчас:Угловой 1.5: динамическая загрузка компонента

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

Теперь <my-cell-component> может иметь некоторые базовые ng-switch о том, что обрабатывает очевидные случаи, как, если значение текст или изображение, или что-то, но так как это будет использоваться многими людьми и во многих проектах, возможно, что кто-то захочет сделать что-то необычное и/или очень специфично внутри ячейки. Они могут просто помещают <my-cell-component> с более ng-switch es, но тогда они возится с базовым кодом рамки, который повреждает ремонтопригодность.

В идеале, я хотел бы сделать что-то, где разработчик может дополнительно предоставить свой собственный шаблон для определенного поля в метаданных, например. metadata.columns[3].customCellComponentName = 'some-custom-template'; Тогда <my-row-component> будет выглядеть примерно так:

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

Проект автоматически помещает все шаблоны в $ templateCache, поэтому разрешения шаблона не должно быть проблемой, но кроме этого, отмеченной линии с «?? ?» очевидно, не работает. Он демонстрирует, чего я хотел бы достичь, но я не знаю, как на самом деле сделать что-то подобное. Я заглянул в переключение, ng-include и другие решения, но ни один из них не предоставляет возможность динамически загружать шаблон и привязывать к нему некоторые данные.

Любые идеи приветствуются. Я хотел бы оставаться как можно дальше от слишком сложных директив. Хотя они позволяют вам многое делать, по моему опыту они также являются кошмаром для отладки и поддержки.

Спасибо.

ответ

0

Вы можете создать директиву для своего <my-cell-component> таким образом, чтобы он принимал templateUrl или определял templateUrl и использует его. Позвольте мне дать вам пример для последнего,

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

Итак, мы получили шаблон Директивы, имеющий ng-include, который использует templateUrl определяется на основе некоторых констант, скажем CELL_TYPE.

Теперь у вас есть директива, которая динамически загружает свой шаблон на основе ваших атрибутов!

Вы можете (очевидно) избавиться от $watch, если динамическое изменение templateUrl не относится к вашему прецеденту.

Смежные вопросы