在表单中设置值时,Observable不会更改

时间:2018-11-03 13:52:48

标签: angular rxjs angular-forms

我有一个表格,您可以在其中选择要显示的位置。

  • 它具有一个带位置列表(第32行)的Observable(locations$)。
  • 它具有formControl值(第38行)的Observable(locationCode$
  • 我创建了一个新的Observable(location$),它给出了列表中与所选项目具有相同代码的位置(第41行)。
  • 然后在屏幕上显示location$可观察到的内容(第16行)

当您在列表中选择一个项目时,下面的location$就会更改,从而可以正常工作。

但是我想在初始加载时设置组合框(第46行),并在视图中显示该位置,所以我无法工作。表单show null首次加载时,但组合框已设置了初始值。

我看到locationCode$可以观察到的更改(请参见第43行和控制台),location$也可以观察到的更改(请参见第44行和控制台),但是视图却没有。

我尝试将代码放入OnAfterViewInit()中,但这也无济于事。

我知道我可以使用不可观察的字段并使用this.location$.subscribe(i => this.location = i);进行更新,并且可以正常工作。但这对我来说就像是骇客。

https://stackblitz.com/edit/angular-rxjs-form-test中查看此内容,了解我的意思。

@Component({
  selector: 'my-app',
  template: `
    <div [formGroup]="form">
        Select: <select formControlName="locationCode" name="locationCode">
            <option [value]="null">-- Pick one --</option>
            <option value="1">Show location 1</option>
            <option value="2">Show location 2</option>
            <option value="3">Show location 3</option>
        </select>
        <div>Selected location: {{ location$ | async | json }}</div>
    </div>`
})
export class AppComponent implements OnInit {
  form: FormGroup;
  locationCode$: Observable<string>;
  locations$: Observable<{ code: string; name: string; }[]>;
  location$: Observable<{ code: string; name: string; }>;

  constructor(private builder: FormBuilder) {
    this.form = this.builder.group({
      locationCode: this.builder.control(null)
    });
  }

  ngOnInit() {
    this.locations$ = of([
      { code: '1', name: 'Location 1', city: 'London' },
      { code: '2', name: 'Location 2', city: 'Amsterdam' },
      { code: '3', name: 'Location 3', city: 'Madrid' }
    ]);

    this.locationCode$ = this.form.controls['locationCode'].valueChanges as Observable<string>;
    this.location$ = combineLatest(this.locationCode$, this.locations$)
      .pipe(
        map(([locationCode, locations]) => locations.find(l => l.code === locationCode))
      );
    this.locationCode$.subscribe(i => console.log('locationCode$: ', i))
    this.location$.subscribe(i => console.log('location$    : ', i))
    // I want to set the selected iten here and see the location$ Observable change
    this.form.controls.locationCode.setValue('2');
  }
}

1 个答案:

答案 0 :(得分:0)

问题在于,在您调用setValue()之后,Angular订阅了可观察对象,因此它没有任何价值。

可能的解决方案可以是:

使用startWith运算符:

this.form.controls['locationCode'].valueChanges.pipe(startWith('2'))

使用setTimeout

setTimeout(() => {
  this.form.controls.locationCode.setValue('2');
})

现在,当Angular订阅该值时,它将获得正确的初始值。