TypeScript Angular ReactiveForms 2方式属性绑定

时间:2018-11-04 16:32:22

标签: angular typescript data-binding angular-reactive-forms

早上好

我正在用Angular 6,Java Spring和mysql数据库构建一个webApplication。 我建立了一个表格,该表格将用于创建和更新客户数据。

在创建客户时,数据会使用REST传递到服务器,这很好,因为google的控制台输出对我来说是一个json字符串,该字符串将表单模型和键入该表单的数据相关联。

我的问题是更新时,我用客户数据填充表单,但提交时,Google的控制台在我的帖子请求中输出了一个空对象。

我的表格:

<div class="container spacer borders" *ngIf="showClientForm">
  <form [formGroup]="form" (ngSubmit)="updateClient(this.form.value)">
    <div class="form-row">
      <div class="form-group col-md-6">
        <p><b>Edition Client</b></p>
        <input  type="text" 
                class="form-control" 
                id="name" 
                placeholder="Raison sociale ou Nom et Prénom" 
                [(value)]="selectedClient.nom"
                formControlName = "nom"
                />
        <input  type="text" 
                class="form-control small-spacer" 
                id="email" 
                placeholder="Raison sociale ou Nom et Prénom" 
                [(value)]="selectedClient.email"
                formControlName = "email"
                />
      </div>
      <div class="form-check-inline col-md-6">
        <input  class="form-check-input" 
                type="radio" 
                id="type_particulier" 
                name="typeClient" 
                [(value)]="selectedClient.value"
                formControlName = "typeClient"
                />
        <label class="form-check-label" for="type_particulier">
          Particulier
        </label>
        <input  class="form-check-input spacer-left" 
                type="radio" 
                name="typeClient" 
                id="type_professionnel" 
                [(value)]="selectedClient.value"
                formControlName="typeClient"
                />
        <label class="form-check-label" for="type_professionnel">
          Professionnel
        </label>
      </div>
    </div>
    <div class="form-row spacer">
      <div class="form-group col-md-6 spacer" formGroupName="adresseFacturation">
        <p><b>Adresse Facturation</b></p>
        <input  type="text" 
                class="form-control" 
                id="adr_fact" 
                placeholder="Numéro, voie ..." 
                [(value)]="selectedClient.adresseFacturation.rue"
                formControlName="rue"
                />
        <input  type="text" 
                class="form-control small-spacer" 
                id="adr_fact" 
                placeholder="Complément d'adresse" 
                [(value)]="selectedClient.adresseFacturation.complement"
                formControlName="complement"
                />
        <div class="form-row">
          <div class="col-md-6">
            <input  type="text" 
                    class="form-control small-spacer" 
                    id="gc_cp" 
                    placeholder="Code Postal" 
                    [(value)]="selectedClient.adresseFacturation.codePostal"
                    formControlName="codePostal"
                    />
          </div>
          <div class="col-md-6">
            <input  type="text" 
                    class="form-control small-spacer" 
                    id="gc_ville" 
                    placeholder="Ville" 
                    [(value)]="selectedClient.adresseFacturation.ville"
                    formControlName="ville"
                    />
          </div>

        </div>
      </div>
      <div class="form-group col-md-6 spacer" formGroupName="adresseTravaux">
          <p><b>Adresse Travaux</b></p>
          <input  type="text" 
                  class="form-control" 
                  id="adr_fact" 
                  placeholder="Numéro, voie ..." 
                  [(value)]="selectedClient.adresseTravaux.rue"
                  formControlName="rue"
                  />
          <input  type="text" 
                  class="form-control small-spacer" 
                  id="adr_fact" 
                  placeholder="Complément d'adresse" 
                  [(value)]="selectedClient.adresseTravaux.complement"
                  formControlName="complement"
                  />
          <div class="form-row">
            <div class="col-md-6">
              <input  type="text" 
                      class="form-control small-spacer" 
                      id="gc_cp" 
                      placeholder="Code Postal" 
                      [(value)]="selectedClient.adresseTravaux.codePostal"
                      formControlName="codePostal"
                      />
            </div>
            <div class="col-md-6">
              <input  type="text" 
                      class="form-control small-spacer" 
                      id="gc_ville" 
                      placeholder="Ville" 
                      [(value)]="selectedClient.adresseTravaux.ville"
                      formControlName="ville"
                      />
            </div>

          </div>
        </div>
    </div>
    <div class="spacer">
      <button class="btn btn-dark" type="submit">Enregistrer</button>
      <button class="btn btn-dark spacer-left" type="button" (click)="returnToList()">Retour</button>
    </div>

  </form>
</div>

当我在每个输入字段上删除[(value)]="selectedClient.nom"时,我可以使用该表单创建客户,但是当我尝试绑定value属性以便用客户填充值来更新此值时,该表单模型没有考虑到它。

这是我的.ts组件,其中包括以下模型:

import { Component, OnInit } from '@angular/core';
import { ClientService } from '../services/client.service';
import { FormBuilder, FormGroup } from '@angular/forms';

@Component({
  selector: 'app-gest-clients',
  templateUrl: './gest-clients.component.html',
  styleUrls: ['./gest-clients.component.css']
})
export class GestClientsComponent implements OnInit {

  clients:Array<Object> = [];
  selectedClient;
  showClientForm = false;
  showNewClientForm = false;
  form:FormGroup;
  msg;


  constructor(private clientService:ClientService,
              private formBuilder:FormBuilder) { }

  ngOnInit() {
    this.clientService.GetClientList().subscribe(
      data => this.handleContent(data)
    );
    this.form = this.formBuilder.group({
      'id':'',
      'nom':'',
      'email':'',
      'adresseFacturation' : this.formBuilder.group({
        'id':'',
        'rue':'',
        'complement':'',
        'ville':'',
        'codePostal':'',
        'complementCodePostal':'',
        'supprimer':''
      }),
      'adresseTravaux' : this.formBuilder.group({
        'id':'',
        'rue':'',
        'complement':'',
        'ville':'',
        'codePostal':'',
        'complementCodePostal':'',
        'supprimer':''
      }),
      'typeClient':'',
      'supprimer':''
    });




  }

  selectClient(client){
    this.showClientForm = true;
    this.selectedClient = client;
  }

  deleteClient(Client){

  }

  handleContent(data){
    this.clients = data;
  }

  updateClient(data){
    console.log(data) **// Empty json string (model only) KO**
    this.clientService.updClient(data).subscribe(
      res => this.msg = res,
      error => this.msg = error
    )
  }

  returnToList(){
    this.form.reset()
    this.selectedClient = null;
    this.showClientForm = false;
    this.showNewClientForm = false;

  }

  addNew(){
    this.showNewClientForm = true;
  }

  AddNewClient(clientFormData){
    console.log(clientFormData) // Correct json string (model + data) ok
    this.clientService.CreateNewClient(clientFormData).subscribe(
      res => this.msg = res,
      error => this.msg = error
    )

  }

}

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { RouterModule } from '@angular/router';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';

import { AppComponent } from './app.component';
import { NavbarComponent } from './navbar/navbar.component';
import { DevisComponent } from './devis/devis.component';
import { CommandeComponent } from './commande/commande.component';
import { GestDevisComponent } from './gest-devis/gest-devis.component';
import { GestCommandeComponent } from './gest-commande/gest-commande.component';
import { GestClientsComponent } from './gest-clients/gest-clients.component';
import { GestFournisseursComponent } from './gest-fournisseurs/gest-fournisseurs.component';
import { GestMaterielsComponent } from './gest-materiels/gest-materiels.component';
import { GestPrestationsComponent } from './gest-prestations/gest-prestations.component';
import { MaterielComponent } from './materiel/materiel.component';
import { PrestationComponent } from './prestation/prestation.component';
import { HomeComponent } from './home/home.component';
import { ClientService } from './services/client.service';

const routes = [
  {path:"", component:HomeComponent},
  {path:"devis", component:DevisComponent},
  {path:"commande", component:CommandeComponent},
  {path:"materiel", component:MaterielComponent},
  {path:"prestation", component:PrestationComponent},
  {path:"gestDevis", component:GestDevisComponent},
  {path:"gestCommandes", component:GestCommandeComponent},
  {path:"gestFournisseurs", component:GestFournisseursComponent},
  {path:"gestMateriels", component:GestMaterielsComponent},
  {path:"gestClients", component:GestClientsComponent},
  {path:"gestPrestations", component:GestPrestationsComponent}

]

@NgModule({
  declarations: [
    AppComponent,
    NavbarComponent,
    DevisComponent,
    CommandeComponent,
    GestDevisComponent,
    GestCommandeComponent,
    GestClientsComponent,
    GestFournisseursComponent,
    GestMaterielsComponent,
    GestPrestationsComponent,
    MaterielComponent,
    PrestationComponent,
    HomeComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule,
    RouterModule.forRoot(routes),
    FormsModule, ReactiveFormsModule
  ],
  providers: [ClientService],
  bootstrap: [AppComponent]
})
export class AppModule { }

3 个答案:

答案 0 :(得分:0)

萨鲁特·菲利普(Salut Philippe)

只需更改ngSubmit并删除参数=>     (ngSubmit)=“ updateClient()”

在updateClient()中反映此更改,只需使用this.form

updateClient(){
  console.log(this.form.value) // ** should print your updated customer object
  etc ...
}

A + 菲利普

答案 1 :(得分:0)

只需从属性绑定中删除括号()并仅使用方括号即可。

<input  type="text" 
            class="form-control" 
            id="adr_fact" 
            placeholder="Numéro, voie ..." 
            [value]="selectedClient.adresseFacturation.rue"
            formControlName="rue"
            />

答案 2 :(得分:0)

我终于在角度文档中找到了解决方案。如文档所述,您不应直接在html中直接定义表单标签属性值,而应在.ts中使用setValue / patchvalue方法。此方法设置表单中每个FormControl中的默认值。我还找到了为表单中的嵌入元素设置值的解决方案。我的代码不是最漂亮的,但是到目前为止,它仍然有效:

import { Component, OnInit } from '@angular/core';
import { ClientService } from '../services/client.service';
import { FormBuilder, FormGroup } from '@angular/forms';

@Component({
  selector: 'app-gest-clients',
  templateUrl: './gest-clients.component.html',
  styleUrls: ['./gest-clients.component.css']
})
export class GestClientsComponent implements OnInit {

  clients:Array<Object> = [];
  selectedClient;
  showClientForm = false;
  showNewClientForm = false;
  form:FormGroup;
  msg;


  constructor(private clientService:ClientService,
              private formBuilder:FormBuilder) { }

  ngOnInit() {
    this.clientService.GetClientList().subscribe(
      data => this.handleContent(data)
    );
    this.form = this.formBuilder.group({
      'id':'',
      'nom':'',
      'email':'',
      'adresseFacturation' : this.formBuilder.group({
        'id':'',
        'rue':'',
        'complement':'',
        'ville':'',
        'codePostal':'',
        'complementCodePostal':'',
        'supprimer':''
      }),
      'adresseTravaux' : this.formBuilder.group({
        'id':'',
        'rue':'',
        'complement':'',
        'ville':'',
        'codePostal':'',
        'complementCodePostal':'',
        'supprimer':''
      }),
      'typeClient':'',
      'supprimer':''
    });

  }


  selectClient(client){
    this.showClientForm = true;
    this.selectedClient = client;

    // sets the default value for the first lyer of elements in my form model
    this.form.patchValue({
      'id':this.selectedClient.id,
      'nom':this.selectedClient.nom,
      'email':this.selectedClient.email,
      'typeClient':this.selectedClient.typeClient,
      'supprimer':this.selectedClient.supprimer
    });

    // sets the default value for embedded elements in the form model 
    // Invoicing address
    (<FormGroup>this.form.controls['adresseFacturation']).controls['id'].patchValue(this.selectedClient.adresseFacturation.id);
    (<FormGroup>this.form.controls['adresseFacturation']).controls['rue'].patchValue(this.selectedClient.adresseFacturation.rue);
    (<FormGroup>this.form.controls['adresseFacturation']).controls['complement'].patchValue(this.selectedClient.adresseFacturation.complement);
    (<FormGroup>this.form.controls['adresseFacturation']).controls['ville'].patchValue(this.selectedClient.adresseFacturation.ville);
    (<FormGroup>this.form.controls['adresseFacturation']).controls['codePostal'].patchValue(this.selectedClient.adresseFacturation.codePostal);
    (<FormGroup>this.form.controls['adresseFacturation']).controls['complementCodePostal'].patchValue(this.selectedClient.adresseFacturation.complementCodePostal);
    (<FormGroup>this.form.controls['adresseFacturation']).controls['supprimer'].patchValue(this.selectedClient.adresseFacturation.supprimer);
    // works address

    // handling null value 
    if(this.selectedClient.adresseTravaux==null){
      (<FormGroup>this.form.controls['adresseTravaux']).controls['id'].patchValue("");
    (<FormGroup>this.form.controls['adresseTravaux']).controls['rue'].patchValue("");
    (<FormGroup>this.form.controls['adresseTravaux']).controls['complement'].patchValue("");
    (<FormGroup>this.form.controls['adresseTravaux']).controls['ville'].patchValue("");
    (<FormGroup>this.form.controls['adresseTravaux']).controls['codePostal'].patchValue("");
    (<FormGroup>this.form.controls['adresseTravaux']).controls['complementCodePostal'].patchValue("");
    (<FormGroup>this.form.controls['adresseTravaux']).controls['supprimer'].patchValue("");
    }else{
      (<FormGroup>this.form.controls['adresseTravaux']).controls['id'].patchValue(this.selectedClient.adresseTravaux.id);
    (<FormGroup>this.form.controls['adresseTravaux']).controls['rue'].patchValue(this.selectedClient.adresseTravaux.rue);
    (<FormGroup>this.form.controls['adresseTravaux']).controls['complement'].patchValue(this.selectedClient.adresseTravaux.complement);
    (<FormGroup>this.form.controls['adresseTravaux']).controls['ville'].patchValue(this.selectedClient.adresseTravaux.ville);
    (<FormGroup>this.form.controls['adresseTravaux']).controls['codePostal'].patchValue(this.selectedClient.adresseTravaux.codePostal);
    (<FormGroup>this.form.controls['adresseTravaux']).controls['complementCodePostal'].patchValue(this.selectedClient.adresseTravaux.complementCodePostal);
    (<FormGroup>this.form.controls['adresseTravaux']).controls['supprimer'].patchValue(this.selectedClient.adresseTravaux.supprimer);
    }




    /**
     * Information found from another post in stackoverflow which led me onto the right way of using setValue or PatchValue
     * 
     * . Using setValue()

    this.userForm.setValue({name: 'Mahesh', age: '20' });

    It is necessary to mention all from controls in setValue() otherwise it will throw error. 

    2. Using patchValue()

    this.userForm.patchValue({name: 'Mahesh'}); 

    When we use patchValue() then it is not necessary to mention all form controls.
    */


  }

  deleteClient(Client){

  }

  handleContent(data){
    this.clients = data;
  }

  updateClient(data){
    console.log(data)
    this.clientService.updClient(data).subscribe(
      res => this.msg = res,
      error => this.msg = error
    )
  }

  returnToList(){
    this.form.reset()
    this.selectedClient = null;
    this.showClientForm = false;
    this.showNewClientForm = false;

  }

  addNew(){
    this.showNewClientForm = true;
  }

  AddNewClient(clientFormData){
    console.log(clientFormData)
    this.clientService.CreateNewClient(clientFormData).subscribe(
      res => this.msg = res,
      error => this.msg = error
    )

  }

}