2017-07-28 53 views
5

这是一个带有双向绑定输入字段的窗体。目标是创建相同的表单来编辑和创建数据。这已经完成了,但我确信可以有更好的方法来做到这一点(如使用AbstractControl功能)。我也错过了这里的一个修复 - 如果clickEdit()被点击需要更新用户想要编辑的对象的表单值。感谢您的帮助和有关AbstractControlNgModel特别说明..用于创建和编辑数据的相同形式Angular4

<div> 
<form (ngSubmit)="clicked ? onEditSubmit($event) : onRegisterSubmit($event)" [formGroup] = "form"> 
    <div class="form-group"> 
    <label>Full Name</label> 
    <input type="text" [(ngModel)]="fullname" formControlName="fullname" class="form-control" > 

    </div> 
    <div class="form-group"> 
    <label>Username</label> 
    <input type="text" [(ngModel)]="username" formControlName="username" class="form-control" > 
    </div> 
    <div class="form-group"> 
    <label>Email</label> 
    <input type="text" [(ngModel)]="email" formControlName="email" class="form-control" > 
    </div> 
    <div class="form-group"> 
    <label>Password</label> 
    <input type="password" [(ngModel)]="password" formControlName="password" class="form-control"> 
    </div> 
    <button type="submit" class="btn btn-primary" [disabled]="!form.valid"> Submit </button> 
</form> 
</div> 

<br> 
<br> 

<table border="2" class="table table-striped"> 
<tr> 
    <th>Full Name</th> 
    <th>Username</th> 
    <th>Email</th> 
    <th>Password</th> 
    <th>Delete</th> 
    <th>Edit</th> 
</tr> 
<div > </div> 
<tr *ngFor="let user of userDetails; index as i"> 
    <td>{{user.fullname}}</td> 
    <td>{{user.username}}</td> 
    <td>{{user.email}}</td> 
    <td>{{user.password}}</td> 
    <td><button (click)="userDelete()">X</button></td> 
    <td><button (click)="clickEdit(i)">Edit</button></td> 
</tr> 
</table> 

而且

import { Component } from '@angular/core'; 
import { initializeApp, database } from 'firebase'; 
import { FormControl, FormGroup, Validators } from '@angular/forms'; 


@Component({ 
    selector: 'app-root', 
    templateUrl: './app.component.html', 
    styleUrls: ['./app.component.css'], 
}) 
export class AppComponent { 

    fullname : string; 
    username : string; 
    email : string; 
    password : string; 

    clicked = false; 

    userDetails:Array<object>; 

    form; 

    ngOnInit() { 
    this.userDetails=[]; 
    this.form = new FormGroup({ 
     fullname : new FormControl("", Validators.required), 
     username : new FormControl("", Validators.required), 
     email : new FormControl("", Validators.required), 
     password : new FormControl("", Validators.required) 
    }); 
    } 

    onRegisterSubmit(e){ 
    let user = { 
     fullname : this.fullname , 
     username : this.username, 
     email : this.email , 
     password : this.password 
    } 
    this.userDetails.push(user); 
    this.clearInputFields(e); 
    } 

    editIndex = null; 

    clickEdit(i){ 
    this.clicked = !this.clicked; 
    this.editIndex = i; 
    } 

    onEditSubmit(e) { 
    let editUser = { 
     fullname : this.fullname , 
     username : this.username, 
     email : this.email , 
     password : this.password 
    } 
    this.userDetails[this.editIndex] = editUser; 
    this.clearInputFields(e); 
    this.clicked = !this.clicked; 
    } 

    clearInputFields(e){ 
    let all = e.target.querySelectorAll('input'); 
    Object.keys(all).forEach(key => { 
     console.log(all[key].value = ''); 
    });  
    } 
} 

回答

4

我会做了不少改变你的形式。因为您使用的是反应形式,因此这里完全是多余的。改用它并删除所有的ngModel。您从表单中获得的对象与您的user相匹配,因此您可以执行的操作只是将该值按原样推送到数组中。

所以你的模板应该是这个样子(简称,作为代码的其余部分):

<form (ngSubmit)="onRegisterSubmit(form)" [formGroup] = "form"> 
    <input type="text" formControlName="username" class="form-control" > 
    <input type="submit" class="btn btn-primary" value="Submit" [disabled]="!form.valid"> 
</form> 

在我在这种情况下使用隐藏域的形式构建,这也是从表单对象中排除,因为它是disabled。这是我们的帮手,所以我们可以区分这是新的user,还是编辑user。该值保存阵列中user的索引。所以如果这个值存在,我们知道要更新数组中的对象,如果该值不存在,让我们将用户推送到数组。

这可以通过多种方式解决,但以上是一种选择。

this.form = this.fb.group({ 
    index: [{value: null, disabled:true}] 
    username : ['', Validators.required], 
    email : ['', Validators.required], 
}); 

所以,根据上述情况,我们可以通过修改onRegisterSubmit看起来像下面这样:

onRegisterSubmit(form) { 
    // since field is disabled, we need to use 'getRawValue' 
    let index = form.getRawValue().index 
    if(index != null) { 
    this.userDetails[index] = form.value 
    } else { 
    this.userDetails.push(form.value)  
    } 
    this.form.reset() // reset form to empty 
} 

当我们要编辑用户,我们通过指数和模板用户

<tr *ngFor="let user of userDetails; let i = index"> 
    <td>{{user.username}}</td> 
    <td>{{user.email}}</td> 
    <td><button (click)="userEdit(user, i)">Edit</button></td> 
</tr> 

然后我们用setValue(或patchValue),以与现有的数值输入字段:

userEdit(user, i) { 
    this.form.setValue({ 
    index: i, 
    username: user.username, 
    email: user.email 
    }) 
} 

应该这样做!所以现在我们可以看到我们可以简化代码并摆脱一些不必要的东西! :)

+0

非常感谢您的详细解答。我没有从头开始制作这个表单,我只是实现了一些功能,是的,我也认为这里不需要ngModel。但你的答案看起来不错,我会详细探讨它。干杯! –

+1

当然,让我知道如果您遇到任何问题,我很乐意提供帮助。我测试了上面的代码,所以它肯定应该工作:) – Alex

相关问题