Angular 响应式表单 - 从数组中读取/设置值

Angular Reactive Forms - Read / Set value from array

我有 3 个文件:

对于我的大部分输入,我的表单都正确地从服务/表单生成器读取数据。我遇到困难的区域是使用 Angular Material Select (下拉)片段。

在我的 component.ts 文件中,我有两个选项供用户 select 使用。 select编辑后,该选项将作为字符串保存到 firestore。

正如您在下面看到的,目前我的 HTML 当前正在从其关联的 component.ts 文件中读取一个数组。理想情况下,我希望它显示来自 firestore 的当前值,并在单击它时显示两个可用选项。

如何在 HTML 中提供这两个选项以及显示 firestore 中的当前设置值?

服务

export interface IUserSettings {
  usersetting_dateformat: string;
}

@Injectable()

export class SettingsService {

  // Database
  private settingsDocRef: AngularFirestoreDocument<any>;
  settingsDocument: Observable<any>;

  // User
  userID: string;

  // Form
  editForm = new FormGroup({});

  // User Settings Behaviour Subject 
  userSettings$: BehaviorSubject<IUserSettings>;

  constructor(
    private readonly afs: AngularFirestore, fb: FormBuilder) {

    this.editForm = fb.group({
      usersetting_dateformat: [''],
    });

    this.userSettings$ = new BehaviorSubject({
      dateformat: 'DD/MM/YYYY',
    });

  }

  getSettingsData() {
    this.settingsDocRef = this.afs.doc(`settings/${this.userID}`);
    this.settingsDocument = this.settingsDocRef.snapshotChanges();
    this.settingsDocument.subscribe(value => {
      const userSettings = value.payload.data() as IUserSettings;
      this.userSettings$.next(userSettings);
      this.editForm.patchValue(this.userSettings$.getValue());
    });
  }

}

Component.ts

... 

  dateFormats = ["DD/MM/YYYY", "MM/DD/YYYY"];

...

Component.html

 <form [formGroup]="settingsService.editForm">
    <mat-select placeholder="Date Format">
        <mat-option *ngFor="let dateFormat of dateFormats" [value]="dateFormat"> {{dateFormat}} </mat-option>
    </mat-select>
</form>

当您已经获得值然后调用表单上的 patchValue 方法时,不确定为什么要用 BehaviourSubject 不必要地使它复杂化。

您可以通过删除 BehaviorSubject 的使用来简化代码,如下所示:

export interface UserSettings {
  dateFormat: string;
}

@Injectable()
export class SettingsService {

  // Database
  private settingsDocRef: AngularFirestoreDocument<any>;
  settingsDocument: Observable<any>;

  // User
  userID: string;

  // Form
  editForm = new FormGroup({});

  constructor(
    private readonly afs: AngularFirestore,
    fb: FormBuilder
  ) {
    this.editForm = fb.group({
      dateFormat: [],
    });
  }

  getSettingsData() {
    this.settingsDocRef = this.afs.doc(`settings/${this.userID}`);
    this.settingsDocument = this.settingsDocRef.snapshotChanges();
    this.settingsDocument.subscribe(value => {
      const userSettings = value.payload.data() as UserSettings;
      this.editForm.patchValue(userSettings);
    });
  }

}

然后您只需要在模板中添加 formControlName

<form [formGroup]="settingsService.editForm">
  <mat-select placeholder="Date Format" formControlName="dateFormat">
    <mat-option *ngFor="let dateFormat of dateFormats" [value]="dateFormat">
      {{dateFormat}}
    </mat-option>
  </mat-select>
</form>

这应该可以解决您的问题。这是一个 Sample StackBlitz 供您参考。没有与您的示例相同的代码。但是应该给你一个上下文。

TL;DR; 您只需要使用该值初始化 FormControl,然后将 formControlName 属性添加到您的表单模板即可完成此工作.