角度:如何使NgControl仅对主机< input>的valueChanges做出反应 [英] Angular: how to make NgControl react to valueChanges only of the host <input>
问题描述
我在<input>
元素上使用指令,并获得对它的控件的引用,如下所示:
I am using a directive on an <input>
-element and get a reference to its controls like this:
@ContentChild(NgControl) private readonly _inputNgControl: NgControl;
但是当我像这样听模型更改时:
But when I listen to model-changes like so:
ngAfterContentInit(): void {
this._inputNgControl.control.valueChanges
.distinctUntilChanged()
.subscribe(value => {
// ...
});
}
看来,this._inputNgControl.control
不是指指令所在的输入,而是指父组件中的所有输入(它包含同一指令的多个<input>
元素),因为我从所有这些输入是在父级中输入的,而不仅仅是我在其中输入内容的输入.
it appears that this._inputNgControl.control
refers not to the input that the directive is sitting on, but to ALL inputs in my parent component (which contains multiple <input>
-elements with the same directive) because I get changes from all of those inputs in the parent and not only the one where I typed something.
那么我该如何过滤仅活动输入的valueChange?我是否需要使用构造函数来注入它,这会使NgControl成为局部而不是全局的吗?还是我需要使用forwardRef自己实现VALUE_ACCESSOR(据我所知,这是NgControl所做的事情)?
So how can I filter the valueChange's of only the active input? Do I need to use the constructor to inject it, will that make the NgControl local instead of global? Or do I need to implement VALUE_ACCESSOR myself with forwardRef (which is what NgControl is doing as far as I understand it)?
最不干净的解决方案是将id传递给指令和make
The least clean solution would be passing an id to the directive and make
.filter(() => this._directiveId === this._inputNgControl.name)
所以我想避免这种情况.
so I want to avoid that if possible.
推荐答案
使用HostListener有所帮助.到目前为止,我一直在使用HostListener来处理本机浏览器事件,例如听键盘操作或鼠标滚动,但是我不知道您可以使用它们来访问host元素的输出(因此名称为host listener,duh !)
What helped was to use HostListener. I have been using HostListener so far only to handle native browser events, like listening to keyboard actions or mouse scrolling, but I had no idea you can use them to get access to the outputs of the host element (thus the name host listener, duh!) as well:
@HostListener('ngModelChange', ['$event'])
onModelChange(value: string | number) { this.modelChange$.next(value); }
然后在具有ContentChild的组件中:
And then in the component with the 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.
})
}
}
这篇关于角度:如何使NgControl仅对主机< input>的valueChanges做出反应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!