1

我有自动完成表单控件:

@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>

我遇到的问题是:

  1. 组件加载,我valuestore.
  2. 用户在输入文本字段中输入内容。
  3. 用户停止输入 350 毫秒(debounce时间)。
  4. emit重视父母并使用Action+Reducer将值保留在商店中。
  5. this.value$对更改和触发方法Observable做出反应。storengOnChange
  6. 用户继续输入。
  7. 来自store覆盖用户已经键入的值。

例如,用户输入“stri”,然后稍作停顿,然后输入“string”,但“store”值覆盖了他的“string”值,他得到了我之前放入“store”的“stri”值。有没有人遇到过这个?我们提出的唯一解决方案是检查焦点并且不设置新值。

4

1 回答 1

1

您正在订阅 ngOnInit 中的更改:

this.autoCompleteControlSubscription = this.autoCompleteControl.valueChanges

还有 ngOnChanges。

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

我要试一试你正在尝试做的事情:

  1. 在初始化时,您可能想要 patchValue然后设置订阅,这样它们就不会相互干扰。

  2. 如果您想在不触发表单的 valueChanges 的情况下修补值,请在没有事件的情况下进行修补:

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

看看我是如何在StackBlitz上使用我自己的 ControlValueAccessor 控件组件执行此操作的。我设置了初始控制值(如果有的话)writeValue

于 2019-06-14T17:58:10.653 回答