Angular。来自订阅的表单控件值

Angular. Form control values from subscription

我有一个必须如下所示的表格: userGroups 的值取自 Web Api,在这里我遇到了问题。 我实现了使用订阅并从 http 获取用户组的功能。表单是在构造函数中创建的。在这种情况下(显然)userGroups 的值未定义,因为它是在订阅中分配的。

export class UserAddComponent implements OnInit {
userForm: FormGroup;
userGroups: UserGroup[];

constructor(
    private http: HttpService,
    private fb: FormBuilder) {
        this.userForm = fb.group({
            'login': ['', [Validators.required]],
            'userGroups': this.fb.array(this.userGroups.map(x => !1)) // userGroups is undefined
        });
    }

    private getUserGroups() {
        this.http.get<ODataResponse>(`${this.soddApiUrl}/UserGroups`)
            .subscribe({
                next: (data: ODataResponse) => {
                    this.userGroups = <UserGroup[]>data.value;
                },
                error: () => { },
                complete: () => { }
            });
    }

    get login() { return this.userForm.get('login'); }
}

我尝试了另一种方法 - 在订阅中创建表单:

export class UserAddComponent implements OnInit {
userForm: FormGroup;
userGroups: UserGroup[];

constructor(
    private http: HttpService,
    private fb: FormBuilder) {
        this.http.get<ODataResponse>(`${this.soddApiUrl}/UserGroups`)
            .subscribe({
                next: (data: ODataResponse) => {
                    this.userGroups = <UserGroup[]>data.value;

                    this.userForm = fb.group({
                        'login': ['', [Validators.required],
                        'userGroups': this.fb.array(this.userGroups.map(x => !1))
                    });
                },
                error: (err) => { },
                complete: () => { }
            });
    }
  
    get login() { return this.userForm.get('login'); } // userFrom is undefined
}

在这种情况下,表单创建得很好,但我得到 login is undefined error in template (because userForm value was assigned in subscription) .

<form [formGroup]="userForm" (ngSubmit)="addUser()">
<div>
    <label for="login" class="label">Login</label>
    <input type="text" nbInput fullWidth id="login" formControlName="login"
          <!-- login is undefined here -->
          [status]="login.dirty ? (login.invalid  ? 'danger' : 'success') : 'basic'"
          [attr.aria-invalid]="login.invalid && login.touched ? true : null" />
</div>

<div>
    <label class="label">User Groups</label>
    <div *ngFor="let userGroup of userGroups; let i = index" formArrayName="userGroups">
        <nb-checkbox [formControlName]="i">{{userGroup.Title}}</nb-checkbox>
    </div>
</div>

所以,在第一种情况下,我无法访问在订阅中分配值的数组,在第二种情况下,我无法获取表单控件的值,因为它不在订阅范围内。

有什么解决方案可以让它工作吗?

谢谢!

将表单创建移动到 OnInit 方法

ngOnInit() {
  this.createForm();
}

private createForm() {
    this.userForm = fb.group({
        'login': ['', [Validators.required]],
        'userGroups': this.fb.array((this.userGroups || []).map(x => !1)) // add empty array to avoid undefined error
    });
}

然后在订阅的方法中再次调用创建表单

yourHttpMethod() {
   this.http.get<ODataResponse>(`${this.soddApiUrl}/UserGroups`)
        .subscribe({
            next: (data: ODataResponse) => {
                this.userGroups = <UserGroup[]>data.value;

                this.createForm();
            },
            error: (err) => { },
            complete: () => { }
        });
}

如果你不能失去初始订阅,那么在订阅中使用patchform。