2017-07-28 23 views
5

İki yolla bağlanmış giriş alanları içeren bir form. Amaç, verileri düzenlemek ve oluşturmak için aynı formu oluşturmaktı. Bu başarıldı, ancak bunu yapmanın daha iyi bir yolu olabileceğine eminim (AbstractControl özelliklerini kullanmak gibi). Ayrıca burada bir düzeltme özledim - clickEdit() tıklandığında, kullanıcının düzenlemek istediği nesne ile form değerlerini güncellemesi gerekiyor. Herhangi bir yardım için teşekkürler ve AbstractControl ve NgModel konusunda özellikle açıklamalar ..Veri oluşturmak ve düzenlemek için aynı form 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> 

Ve

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 = ''); 
    });  
    } 
} 

cevap

4

Ben senin forma epeyce değişiklik yapmak istiyorum. Reaktif bir form kullandığınız için burada ngModel tamamen gereksizdir. Bunun yerine ve ngModel'in tümünü kaldırın. Formdan aldığınız nesne, user ile eşleşiyor, böylece yapabileceğiniz şey, bu değeri diziye olduğu gibi itmektir.

Yani (kod geri kalanı gibi, kısaltılmış) bu gibi görünmelidir şablonunuzu :

<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> 

gizli bir alan kullanılır ben bu durumda sahip formun yapı olarak, o da form nesnesinden disabled olduğu gibi hariç tutuldu. Bu bizim için bir yardımcıdır, bu yüzden bu yeni bir user ise veya bir user düzenliyorsak ayırt edebiliriz. Değer, dizinizden user dizinini tutar. Yani eğer bu değer varsa, dizideki nesneyi güncellemeyi biliyoruz, eğer değer mevcut değilse, kullanıcıyı diziye atalım.

Bu, çeşitli yollarla çözülebilir, ancak yukarıda bir seçenek vardır.

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

Yani yukarıdaki göre, biz benzemeye onRegisterSubmit değiştirebilirsiniz şunlardır:

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 
} 

bir kullanıcıyı düzenlemek istediğinizde, biz endeksi ve şablonda kullanıcıyı geçmesi

<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> 

sonra setValue kullanmak (veya patchValue) mevcut değerlerle alanları girmek için:

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

yapmalı ki! Artık kodunuzu ne kadar basitleştirebileceğimizi ve bazı gereksiz şeylerden kurtulduğumuzu görebiliriz! :)

+0

Detaylı cevap için çok teşekkürler. Bu formu sıfırdan yapmadım, sadece bazı özellikleri uyguladım ve evet, ayrıca ngModel'in burada gerekli olmadığını düşündüm. Ama cevabınız harika görünüyor, ayrıntılı olarak inceleyeceğim. Şerefe! –

+1

Elbette, herhangi bir sorunla karşılaşırsanız ve yardımcı olmaktan memnuniyet duyarız. Yukarıdaki kodu test ettim, bu yüzden kesinlikle işe yaramalı :) – Alex