Angular: как заставить NgControl реагировать на значение только для хоста <input> - PullRequest
0 голосов
/ 06 июня 2018

Я использую директиву для <input> -элемента и получаю ссылку на его элементы управления следующим образом:

@ContentChild(NgControl) private readonly _inputNgControl: NgControl;

Но когда я слушаю изменения модели, например, так:

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

похоже, что this._inputNgControl.control относится не ко входу, на котором находится директива, а ко ВСЕМ входам в моем родительском компоненте (который содержит несколько элементов <input> с одной и той же директивой), потому что я получаю изменения от всехиз этих входов в родительском, а не только тот, где я что-то набрал.

Так как я могу отфильтровать значения valueChange только для активного ввода?Нужно ли мне использовать конструктор для его внедрения, это сделает NgControl локальным, а не глобальным?Или мне нужно самому реализовать VALUE_ACCESSOR с forwardRef (как это делает NgControl, насколько я понимаю)?

Наименее чистым решением было бы передать id в директиву и сделать

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

поэтому я хочу избежать этого, если это возможно.

1 Ответ

0 голосов
/ 06 июня 2018

Что помогло, так это использование HostListener.До сих пор я использовал HostListener только для обработки собственных событий браузера, таких как прослушивание действий клавиатуры или прокрутка мышью, но я понятия не имел, что вы можете использовать их для получения доступа к выходным данным элемента host (таким образом, имя host listener, 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.
    })
  }
}
...