Угловой: Асинхронный канал подписывается на поздний

#angular #typescript #kendo-ui #observable #kendo-ui-angular2

Вопрос:

Моя проблема: у меня есть реактивная форма, которая открывается как новое окно с помощью WindowManager KendoUI.

   public openEditWindow(item: Item): void {
    const window: WindowRef = this.windowService.open({
      title: 'Update Item',
      content: NewComponent,
      top: 12,
      left: 198,
      width: 1259,
      height: 800
    });
    window.content.instance.fillForm(item);

  }
 

Я загружаю данные в эту форму через window.content.instance.fillForm(item);
Класс выглядит примерно так:

 
formgroup: FormGroup
public ProblemChild: Observable<string>;
constructor(formBuilder: formbuilder) {

this.formGroup = formbuilder.group({
name: ['', required]
something: ['']
})

this.problemChild = combineLatest([this.formGroup.controls.name.valueChanges, this.formGroup.controls.something.valuechanges]).pipe(map(/*Do Stuff*/))
}

public fillForm(item: Item): void{
this.formgroup.controls.name.setValue(item.name)
...

}
 

HTML выглядит следующим образом

 <form [formGroup]="formGroup"> 
...
</form>
{{problemChild | async}}
 

fillForm функция вызывается между ctor и функцией OnInit.
Другими словами: я получил все свои данные до того, как компонент будет отрисован, и я problemChild не буду отображать вычисленные данные до тех пор, пока все соответствующие поля не будут снова обновлены пользователем.

Если это не совсем понятно, я сделал небольшую насмешку с таким же поведением https://stackblitz.com/edit/angular-ivy-fqyhwn?file=src/app/app.component.ts здесь темы являются резервными valueChanges для ид кнопка Обновления является резервным для полей ввода

Насколько я понимаю angular, асинхронный канал подписывается на problemChild наблюдаемое, как только компонент визуализируется, и, начиная с этого момента, combineLatest он фактически начнет прослушивать valueChanges . Что привело меня к идее сохранить элемент в переменной и просто задать значения в ngAfterViewInit. Что также не сработало, так как это приводит к тому, что поля ввода (поле kendoTextbox) выглядят так, как будто в них нет значения (метка находится В поле), но поле заполнено, в результате чего метка и текст значения перекрываются. Вам нужно один раз щелкнуть по полю, чтобы оно снова работало правильно. Так что это не вариант.

То, что я сейчас сделал shareReplay() , — это выбрал combineLatest и немедленно подписался на него. Все данные будут отображаться правильно, но теперь я получил случайную подписку, которая ничего не делает. Есть ли лучший способ?

Комментарии:

1. разве вы не можете вызвать форму setValue с setTimeout , чтобы вызвать наблюдаемое?

2. Я мог бы, но это было бы таким же нечистым решением, как и то, которое у меня сейчас есть, ИМО