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

Som*_* S. 4 typescript angular-directive angular

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

<div dir1="red" [dir2]="123">... My Content ...</div>
Run Code Online (Sandbox Code Playgroud)

我发现自己在我的代码中的几个地方使用完全相同的绑定值应用上面的指令.而不是重复自己,我想创建我自己的自定义指令,称之为myDir,我可以像这样应用:

<div MyDir >... My Content ...</div>
Run Code Online (Sandbox Code Playgroud)

这应该与应用完全相同,dir1并且dir2与前面的例子一样,即它将具有值"red"123在其类中进行硬编码.

我已尝试设置主机绑定,如下面的plunker示例,但这不起作用..

我有一个想法是,如果只有打字稿有多重继承,那么我只是简单地写一个MyDir类的扩展名Dir1 Dir2 ..

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

请帮助,谢谢!

https://plnkr.co/edit/W20Wvew326qsGfPU5H6v

Som*_* S. 7

更新:仍然不可能在2018年9月.这是Angular团队的功能积压.按照进度https://github.com/angular/angular/issues/8785

(TL; DR.对于我的黑客解决方案,请参见此处的Plunker)

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

constructor(private elRef: ElementRef, /*...*/) { /*...*/ }
Run Code Online (Sandbox Code Playgroud)

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

我所做的,我只是创建了两个new Dir1/ Dir2在传递对象MyDirElementRef作为上下文Dir1/ Dir2像这样:

// inside MyDir constructor
this.d1 = new Dir1(this.elRef,  /*...*/);
this.d2 = new Dir2(this.elRef,  /*...*/);
Run Code Online (Sandbox Code Playgroud)

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

//inside MyDir constructor
this.d1.dir1 = "red";
this.d2.dir2 = 123;
Run Code Online (Sandbox Code Playgroud)

接下来,我不得不尝试做的是匹配的公共方法d1/ d2MyDir通过调用后者,例如相应的方法(S)内,前者的方法

ngAfterContentInit() {
  this.d1.ngAfterContentInit();
  this.d2.ngAfterContentInit();
}
Run Code Online (Sandbox Code Playgroud)

这是所有拼凑在一起的plunker https://plnkr.co/edit/TCagW8vOPrqSiOT9Oztf


Vah*_*hid 2

从 Angular 15 开始,您可以使用指令组合 API。您正在寻找的是将指令添加到另一个指令

您的示例将是:

@Directive({
  hostDirectives: [Dir1, Dir2],
})
export class MyDir {
  dir1 = inject(Dir1, { self: true });
}
Run Code Online (Sandbox Code Playgroud)