将两个指令合并为一个指令

Consolidating Two Directives into a Single One

假设有两个预定义指令 dir1dir2(由第三方 API 提供,无法控制)。假设这些可以应用于 html 元素,如下所示:

<div dir1="red" [dir2]="123">... My Content ...</div>

我发现自己在我的代码中的多个位置应用了具有完全相同绑定值的上述指令。我不想重复自己,而是想创建自己的自定义指令,将其命名为 myDir,我可以这样应用:

<div MyDir >... My Content ...</div>

这应该 完全 与应用 dir1dir2 相同,如上面的示例,即它将具有值 "red"123 硬编码在 class.

我已尝试按照以下 plunker 示例设置主机绑定,但这不起作用..

我的一个想法是,如果只有打字稿有多重继承,那么我会简单地写 MyDir class Dir1 和 [=43 的扩展=] Dir2..

我的问题是如何编写自定义指令 (MyDir) 以实现预期用途?

请协助, 谢谢你!

https://plnkr.co/edit/W20Wvew326qsGfPU5H6v

Update: Still not possible in May 2020. It is on the Angular Team's feature backlog. Follow progress here https://github.com/angular/angular/issues/8785

(TL;DR。对于我的 hack soln,请参阅 Plunker here)

如上所示,以下是我最终解决问题的方法。请注意,这不是最通用的解决方案;在其他情况下,它的适应性在很大程度上取决于所涉及指令的 public API 是什么样子。它应该在要组合的指令至少具有 ElementRef 作为注入依赖项之一的情况下运行良好,例如:

constructor(private elRef: ElementRef, /*...*/) { /*...*/ }

如果指令负责更改元素的样式,则很可能就是这种情况。

我所做的是,我只是创建了两个 new Dir1/Dir2 对象,将 MyDirElementRef 作为 Dir1/Dir2 像这样:

// inside MyDir constructor
this.d1 = new Dir1(this.elRef,  /*...*/);
this.d2 = new Dir2(this.elRef,  /*...*/);

然后我将 d1/d2 的 public 属性(@Input 绑定)设置为我需要它们永久存在的值(以避免重复自己):

//inside MyDir constructor
this.d1.dir1 = "red";
this.d2.dir2 = 123;

接下来,我所要做的就是通过在相应方法中调用前者的方法,将 public 方法 d1/d2MyDir 相匹配后者的 (s),例如

ngAfterContentInit() {
  this.d1.ngAfterContentInit();
  this.d2.ngAfterContentInit();
}

这是拼凑而成的插件 https://plnkr.co/edit/TCagW8vOPrqSiOT9Oztf