有没有办法为 Angular 1.5 组件动态渲染不同的模板

Posted

技术标签:

【中文标题】有没有办法为 Angular 1.5 组件动态渲染不同的模板【英文标题】:Is there a way to dynamically render different templates for an angular 1.5 component 【发布时间】:2016-12-03 11:39:24 【问题描述】:

我有许多 Angular 1.5 组件,它们都采用相同的属性和数据结构。我认为它们可以重新分解为单个组件,但我需要一种方法来根据 type 属性的插值动态选择模板。

var myComponentDef = 
    bindings: 
        type: '<'
    ,
    templateUrl: // This should be dynamic based on interpolated type value
;

angular.module('myModule').component('myComponent', myComponentDef);

我不能使用templateUrl function($element, $attrs) ,因为$attrs 中的值是未插值的,所以我不会得到传入数据中指定的类型。

我可以只拥有一个带有一系列 ng-ifng-switch 指令的大模板,但我希望将模板分开。

或者,我可以将组件分开并在父组件中使用ng-switch 等,但我不喜欢这样,因为它看起来有很多重复。

我正在寻找一种解决方案,我可以使用传入绑定的插值 type 来匹配每种类型的模板 url,然后使用该模板构建组件。

这可能吗?

谢谢

【问题讨论】:

我认为这是不可能的,因为它需要 $compile 服务,而该服务不适用于组件。不过你可以使用指令。 查看这个简单而优雅的解决方案:***.com/a/41743424/1274852 【参考方案1】:

在任何情况下,您都必须在某处拥有切换逻辑,那么为什么不简单地将其放在父组件模板中呢?

在这种情况下,拥有干净易懂的 An​​gularJS 模板比重复一点 IMO 更有价值:

<ng-container ng-switch="$ctrl.myComponentDef.type">
  <component-type1 ng-switch-when="type1" param="$ctrl.myComponentDef"></component-type1>
  <component-type2 ng-switch-when="type2" param="$ctrl.myComponentDef"></component-type2>
</ng-container>

即使您即时更改 myComponentDef.type,开关中的组件也会正确调用它们各自的 $onDestroy$onInit 方法并按预期加载数据 - 没有魔法,没有巫术。

【讨论】:

【参考方案2】:

这不是专门为组件制造的。该任务缩小到使用带有动态模板的指令。现有的是ng-include

要在组件中使用它,它应该是:

var myComponentDef = 
  bindings: 
    type: '<'
  ,
  template: '<div ng-include="$ctrl.templateUrl">',
  controller: function () 
    this.$onChanges = (changes) => 
      if (changes.type && this.type) 
        this.templateUrl = this.type + '.html';
      
    
  

【讨论】:

感谢您的帮助。我真的很喜欢这个。我在控制器中注入了一个角度常量,其中包含到特定 url 的所有配置映射类型,因此该行可以是 this.templateUrl = typeMapperConfig[this.type];【参考方案3】:

您可以注入任何服务并设置动态网址

angular.module('myApp').component("dynamicTempate", 
        controller: yourController,
        templateUrl: ['$routeParams', function (routeParams) 
           
            return 'app/' + routeParams["yourParam"] + ".html";
        
        ],
        bindings: 
        ,
        require: 
        
    );

【讨论】:

比调用 ng-include 更好的解决方案。 如果你需要传入一个项目来确定 url 应该是什么 您可以注入任何服务并从中获取 url 并返回该 url

以上是关于有没有办法为 Angular 1.5 组件动态渲染不同的模板的主要内容,如果未能解决你的问题,请参考以下文章

Angular 1.5 组件路由器兄弟组件

如何在 Angular 1.5 中从父控制器访问组件方法

Angular - 动态组件渲染错误数据

路由器插座的Angular 2延迟渲染

Angular 1.5 组件属性存在

Angular ui-select2 - 隐藏组件的初始绘图/渲染