2017-07-28 1 views
5

Hier ist ein Formular mit zweifach gebundenen Eingabefeldern. Ziel war es, die gleiche Form zum Bearbeiten und Erstellen von Daten zu erstellen. Das wurde erreicht, aber ich bin mir ziemlich sicher, dass es einen besseren Weg dafür geben könnte (wie die Verwendung von AbstractControl-Funktionen). Ich vermisse auch hier einen Fehler - wenn clickEdit() geklickt wird, müssen die Formularwerte mit dem Objekt aktualisiert werden, das der Benutzer bearbeiten möchte. Vielen Dank für jede Hilfe und vor allem Erklärungen über AbstractControl und NgModel ..Gleiches Formular zum Erstellen und Bearbeiten von Daten 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> 

Und

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

Antwort

4

Ich würde schon einige Änderungen an der Form machen. ngModel ist hier völlig überflüssig, da Sie eine reaktive Form verwenden. Nutzen Sie das stattdessen und entfernen Sie alle ngModels. Das Objekt, das Sie aus dem Formular erhalten, entspricht Ihrem user. Sie können also einfach diesen Wert auf das Array übertragen.

So Ihre Vorlage sollte in etwa so (verkürzt, wie der Rest des Codes) aussehen:

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

Im Build der Form I in diesem Fall ein verstecktes Feld verwendet, das ist auch vom Formularobjekt ausgeschlossen, da es disabled ist. Dies ist ein Helfer für uns, so dass wir unterscheiden können, ob es sich um einen neuen user handelt oder ob wir einen user bearbeiten. Der Wert enthält den Index des user von Ihrem Array. Wenn also dieser Wert existiert, wissen wir, dass wir das Objekt im Array aktualisieren müssen. Wenn der Wert nicht existiert, lasst uns den Benutzer zum Array schieben.

Dies könnte durch zahlreiche Möglichkeiten gelöst werden, aber oben ist eine Option.

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

So die oben nach, können wir die onRegisterSubmit aussehen wie das ändern folgende:

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 
} 

Wenn wir einen Benutzer bearbeiten möchten, übergeben wir den Index und den Benutzer in Vorlage

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

und dann verwenden wir setValue (oder 0.123.) einzugeben, um die Felder mit den vorhandenen Werten:

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

Das sollte es tun! Jetzt können wir sehen, wie viel wir Ihren Code vereinfachen und einige unnötige Dinge loswerden können! :)

+0

Vielen Dank für ausführliche Antwort. Ich habe dieses Formular nicht von Grund auf erstellt, ich habe nur einige Funktionen implementiert und ja, ich dachte auch, dass ngModel hier nicht benötigt wird. Aber deine Antwort sieht gut aus, ich werde es im Detail erkunden. Prost! –

+1

Sicher, lassen Sie mich wissen, wenn Sie irgendwelche Probleme auftreten, und ich bin glücklich zu helfen. Ich habe den obigen Code getestet, also sollte es definitiv funktionieren :) – Alex

Verwandte Themen