Angular:如何使 NgControl 仅对主机的 valueChanges 做出反应 <input>

Angular: how to make NgControl react to valueChanges only of the host <input>

我在 <input> 元素上使用指令并获取对其控件的引用,如下所示:

@ContentChild(NgControl) private readonly _inputNgControl: NgControl;

但是当我听到这样的模型变化时:

  ngAfterContentInit(): void {
    this._inputNgControl.control.valueChanges
      .distinctUntilChanged()
      .subscribe(value => {
         // ...
    });
  }

看来 this._inputNgControl.control 不是指指令所在的输入,而是指我父组件中的所有输入(它包含多个具有相同指令的 <input> 元素),因为我从父级中的所有这些输入中获得更改,而不仅仅是我输入内容的输入。

那么我如何过滤活动输入的 valueChange?我是否需要使用构造函数来注入它,这会使 NgControl 本地化而不是全局化吗?或者我是否需要使用 forwardRef 自己实现 VALUE_ACCESSOR(据我所知,这是 NgControl 正在做的事情)?

最不干净的解决方案是将 id 传递给指令并 make

.filter(() => this._directiveId === this._inputNgControl.name)

所以我想尽可能避免这种情况。

有用的是使用 HostListener。到目前为止,我一直只使用 HostListener 来处理本机浏览器事件,例如监听键盘操作或鼠标滚动,但我不知道您可以使用它们来访问主机元素的输出(因此名称主机监听器,duh !) 还有:

@HostListener('ngModelChange', ['$event'])
onModelChange(value: string | number) { this.modelChange$.next(value); }

然后在带有 ContentChild 的组件中:

@Component({
  selector: input-wrapper',
  template: `<ng-content></ng-content>`
})
export class InputWrapperComponent implements AfterContentInit {
  @ContentChild(InputControllerDirective) private _icd: InputControllerDirective;

  ngAfterContentInit() {
    this._icd.modelChange$.subscribe((value: string | number) => {
       // do sth.
    })
  }
}