Angular 1.5:动态加载组件

Ber*_* G. 6 components angularjs

我正在尝试使用AngularJS 1.5及其组件创建某种通用gridview.我现在所做的(伪代码)版本:

// 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>
Run Code Online (Sandbox Code Playgroud)

现在<my-cell-component>可以有一些ng-switch处理明显情况的基本语句,比如值是文本还是图像什么的,但是由于这将被许多人和许多项目使用,有可能有人想要做一些奇特的事情. /或在细胞内高度特异.他们可能只是ammend <my-cell-component>更多的ng-switchES,但他们与哪些伤害可维护性基本框架代码搞乱.

所以,理想情况下,我想做一些开发人员可以选择为元数据中的特定字段提供自己的自定义模板的东西,例如,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>
Run Code Online (Sandbox Code Playgroud)

该项目自动将所有模板放在$ templateCache中,因此解析模板应该不是问题,但除此之外,带有"???"的标记行 显然不起作用.它展示了我想要实现的目标,但我不知道如何实际做这样的事情.我查看了transclusion ng-include和其他解决方案,但似乎没有提供动态加载模板和模型绑定一些数据的选项.

任何和所有的想法都非常受欢迎.我希望尽可能远离过于复杂的指令.虽然它们允许你做很多事情,但根据我的经验,它们也是调试和可维护性的噩梦.

谢谢.

tan*_*may 0

您可以为您创建一个指令<my-cell-component>,使其接受 atemplateUrl或确定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);
                  }
              });
          }
      };
}]);
Run Code Online (Sandbox Code Playgroud)

因此,我们已经得到了指令的模板ng-include,它使用templateUrl基于一些常量确定的值,例如CELL_TYPE

现在您已经有了一个可以根据您的属性动态加载其模板的指令!

$watch如果动态更改templateUrl不适用于您的用例,您(显然)可以摆脱它。