Angular2:表单构建+异步数据加载

Blu*_*ueM 10 angular2-forms angular

我有一个使用表单生成器(Angular2 Beta 1,TypoScript)创建的表单,即:在这里有类似的东西constructor:

this.form = this._formBuilder.group({
    'username': ['', Validators.required],
    'email': ['', Validators.required]
});
Run Code Online (Sandbox Code Playgroud)

表格显示,到目前为止一切都很好.我没有真正得到的是我如何处理时,我加载数据(在这种情况下:用户对象)的结合从远程服务(或其他一些异步加载机制).

我试过的是:

  • constructor或中异步加载数据ngOnInit.问题:即使在加载开始之前也会引发异常("无法读取未定义的属性'验证者'...")
  • constructor或中异步加载数据ngOnInit,但在此之前创建一个空表单.问题:验证不起作用.
  • 我期望工作:将表单数据绑定到User对象的属性,并设置该对象的属性.问题:没有例外,但数据没有显示在表单中.

我想必须有一些更聪明/更好的方法让这个工作?我对Angular2很新,所以我希望问题不是太愚蠢......

----更新----

首先,我忘了提到我ngFormModel在表格中使用- 如果它很重要.

和@Thierry:我认为"与表单绑定的临时空对象"是我尝试做的(上面提到的第3种方法)但是什么都行不通.确切地说,我试过这个:

constructor(private _formBuilder:FormBuilder) {
    this.user = new User;
    this.user.username = 'abc';
    this.form = this._formBuilder.group({
        'username': [this.user.username, Validators.required],
    });
}
Run Code Online (Sandbox Code Playgroud)

这显示了用户名,但是当我移动设置this.user.username为构造函数末尾的行时它甚至不起作用- 我觉得这很令人惊讶,因为我希望数据绑定能够解决这个问题.

Thi*_*ier 6

我看到了几个解决方案:

  • 利用a *ngIf仅在数据存在时显示表单
  • 利用@CanActivate装饰器(如果使用路由)显示表单所在的组件,仅当数据存在时
  • 使用临时空对象与表单绑定.当数据存在时,您可以使用收到的数据填充(或覆盖)此对象.

这是一个plunkr:https://plnkr.co/edit/metUkOB7Sqfyr9DtCLR0 p = preview .

希望它对你有帮助,蒂埃里


Vla*_*vic 6

您可以在Control对象中分隔您的用户名和电子邮件,而不是将其附加到表单.你将拥有更多的控制权(你可以稍后更新).

form: ControlGroup;
email: Control = new Control("");
name: Control = new Control("");
constructor(public fb: FormBuilder) {
 this.form = fb.group({
        email: this.email,
        name: this.name
    });

    setTimeout(() => {
        this.email.updateValue("invalid email");
        this.name.updateValue("Name");
    }, 3000);
}
Run Code Online (Sandbox Code Playgroud)

Plunker的例子


dfs*_*fsq 5

您还可以在加载数据后更新FormGroup中的各个控件.例如:

this._http.get('/user/123')
    .map(response => response.json())
    .subscribe(user => {
        this.form.find('username').updateValue(user.username);
        this.form.find('email').updateValue(user.email);
    })
Run Code Online (Sandbox Code Playgroud)

重要的是,您可以在formGroup one中找到控件实例并更新其值.或者简单

this.form.controls.username.updateValue(user.username)
Run Code Online (Sandbox Code Playgroud)

也会有用.

  • 小更新,find被删除了...现在是`this.form.get('username').setValue(user.username);` (2认同)