2017-07-28 112 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

相關問題