为什么在 Reactive Form 上插值没有 return 任何值?

Why interpolating on Reactive Form does not return any value?

当从 Observable 进行插值时,控制台记录表单给我空值。

[component.html]

<div>
    <form [formGroup]="mainForm">
      <input formControlName="time"
              value="{{(time|async)}}">
    </form>
    <button (click)="log()">Log</button>
</div>

[component.ts]

mainForm: FormGroup;

time = new Observable<string>((observer: Observer<string>) => {
    setInterval(() => observer.next(new Date().toString()), 1000);
  });


constructor(public fb: FormBuilder){
  this.mainForm = fb.group({
      time: null
    })
}


log(){
  console.log(this.mainForm.value)
}

我真的必须使用 .subscribe(value=> this.mainForm.patch(value)) ??

就没有别的办法了吗?我讨厌取消订阅。

编辑: 请假设 time 作为随机示例。

您的代码中充满了反模式。您正在使用 Reactive Forms 以及输入的 value 属性。您最初将 formControlName 时间的值设置为 null。除非您更改它,否则它将是 null。尽管您正在设置输入的 value 属性,但它不会反映在表单值上。

对此的解决方案是 subscribetime,然后在 time FormControl 上显式调用 setValue。以下是您的操作方式:

import { Component, OnInit } from '@angular/core';
import { Observable, Observer } from 'rxjs';
import { FormGroup, FormBuilder } from '@angular/forms'

@Component({
  selector: 'my-app',
  templateUrl: `app.component.html`,
})
export class AppComponent {

  time = new Observable<string>((observer: Observer<string>) => {
    setInterval(() => observer.next(new Date().toString()), 1000);
  });

  mainForm: FormGroup;

  constructor(public fb: FormBuilder) {
    this.mainForm = fb.group({
      time: null
    });
  }

  ngOnInit() {
    this.time.subscribe(time => {
      this.mainForm.get('time').setValue(time);
    })
  }

  log() {
    console.log(this.mainForm.value)
  }

}

然后,在您的模板中:

<div>
    <form [formGroup]="mainForm">
        <input 
      formControlName="time">
  </form>
  <button (click)="log()">Log</button>
</div>

Here's a Working Sample StackBlitz for your ref.

请不要混用模板驱动和响应式表单!我也认为你的 Observer 东西是 fiddle。我建议改用计时器。是的,您必须退订,请添加。还请使用 $

命名 observable
@Component({
  selector: 'my-app',
  template: `
  <div>
    <form [formGroup]="mainForm">
      <input formControlName="time">
    </form>

    <button (click)="log()">Log</button>
  </div>`
})
export class AppComponent implements OnInit {

  time$ = timer(0, 1000).pipe(
    map(tick => new Date().toString())
  );

  mainForm: FormGroup;

  constructor(public fb: FormBuilder){
    this.mainForm = fb.group({
      time: new FormControl('')
    })
  }

  ngOnInit() {
    this.time$.subscribe(t =>
      this.mainForm.get('time').patchValue(t)
    );
  }

  log(){
    console.log(this.mainForm.get('time').value)
  }
}

编辑:

或者使用模板驱动形式

@Component({
  selector: 'my-app',
  template: `
  <div>
    <form>
      <input [value]="time$ | async">
    </form>

    <button (click)="log()">Log</button>
  </div>`
})
export class AppComponent {

  time$ = timer(0, 1000).pipe(
    map(tick => new Date()),
  );

  log(){ // removed argument 'event'
    this.time$.pipe(
      take(1)
    ).subscribe( t => 
      console.log(t)
    );
  }
}