NgOnChanges переопределяет значение формы управления, когда пользователь вводит - PullRequest
1 голос
/ 14 июня 2019

У меня есть автозаполнение контроля формы:

@Component({
    selector: 'app-autocomplete',
    templateUrl: './app-autocomplete.view.html',
    changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AutoCompleteFilterComponent implements OnInit, OnDestroy, OnChanges {   
@Input() value: any;
@Output() onChanged = new EventEmitter();
autoCompleteControl: FormControl = new FormControl();
private autoCompleteControlSubscription: Subscription;
constructor() { }

ngOnInit(): void {
    this.autoCompleteControl.setValue(this.value, { emitEvent: false });
    this.autoCompleteControlSubscription = this.autoCompleteControl.valueChanges
        .pipe(
            skipUndefined(),
            filter(value => value.length >= 3),
            distinctUntilChanged(),
            debounceTime(350),
            map(value => {                    
                this.onChanged.emit(value.trim());
            })
        ).subscribe();
}

ngOnChanges(changes: SimpleChanges): void {
    if (!changes.value.firstChange) {
        this.autoCompleteControl.setValue(changes.value.currentValue);
    }
}

ngOnDestroy(): void {
    if (this.autoCompleteControlSubscription) {
        this.autoCompleteControlSubscription.unsubscribe();
    }
}

Я получаю начальное значение от store и передаю его как @Input переменную:

this.value$ = this._store$.select(s=>s.value);
<app-autocomplete [value]="value$ | async"></app-autocomplete>

Проблема, с которой я столкнулсяis:

  1. Компонент загружается, и я передаю начальную value из store.
  2. Пользователь вводит что-то в текстовое поле ввода.
  3. Пользователь прекращает печатать для350 мс (debounce время).
  4. I emit значение для родителя и использование Action + Reducer для сохранения значения в хранилище.
  5. this.value $Observable реагирует на store изменение и вызывает метод ngOnChange.
  6. Пользователь продолжает вводить.
  7. Значение из store перезаписывает то, что пользователь уже набрал.

Например, пользователь набрал «stri», затем сделал короткую паузу, затем набрал «string», но значение «store» перезаписывает его значение «string», и он получил значение «stri», которое я передал в «store» перед,Кто-нибудь сталкивался с этим раньше?Единственное решение, которое мы придумали, это проверить фокус и не устанавливать новое значение.

1 Ответ

1 голос
/ 14 июня 2019

Вы подписываетесь на изменения в ngOnInit:

this.autoCompleteControlSubscription = this.autoCompleteControl.valueChanges

И ngOnChanges тоже.

this.autoCompleteControl.setValue(changes.value.currentValue);

Я собираюсь сделать снимок того, что вы пытаетесь сделать:

  1. В init вы можете захотеть patchValue и , а затем настроить подписку, чтобы они не мешали друг другу.

  2. Если вы хотите пропатчить значение без запуска значения valueChanges формы, тогда пропатчите без события:

    this.form.controls[control].patchValue(value, { emitEvent: false });

Посмотрите, как я это делаю, с моим собственным компонентом управления ControlValueAccessor на StackBlitz . Я устанавливаю начальное контрольное значение (если оно есть) с помощью writeValue

...