【问题标题】:Angular 1.5: dynamically load a componentAngular 1.5:动态加载组件
【发布时间】:2016-08-01 09:04:41
【问题描述】:

我正在尝试使用 AngularJS 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>

现在&lt;my-cell-component&gt; 可以有一些基本的ng-switchstatement 来处理明显的情况,比如如果值是文本或图像或其他东西,但由于这将被许多人和许多项目使用,这是可能的有人会想在细胞内做一些花哨和/或高度具体的事情。他们可以只用更多的ng-switches 来修改&lt;my-cell-component&gt;,但随后他们会弄乱基本框架代码,这会损害可维护性。

因此,理想情况下,我想做一些东西,开发人员可以选择为元数据中的特定字段提供自己的自定义模板,例如metadata.columns[3].customCellComponentName = 'some-custom-template'; 然后&lt;my-row-component&gt; 看起来像这样:

<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 和其他解决方案,但似乎都没有提供动态加载模板和模型绑定一些数据的选项。

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

谢谢。

【问题讨论】:

    标签: angularjs components


    【解决方案1】:

    您可以为您的&lt;my-cell-component&gt; 创建一个指令,这样它要么接受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

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

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

    【讨论】:

      猜你喜欢
      • 2017-07-17
      • 1970-01-01
      • 2019-10-19
      • 1970-01-01
      • 2021-05-30
      • 1970-01-01
      • 2016-12-21
      • 2020-04-17
      • 2019-02-06
      相关资源
      最近更新 更多