【问题标题】:can't get values of current item on submit event在提交事件中无法获取当前项目的值
【发布时间】:2019-09-19 23:30:25
【问题描述】:

我有一个 json 对象数组,我绑定到 html 表单和 mat-expansion-panel 视图。我正在尝试更改 name 输入字段的值,但无论如何它都会返回初始值。例如如果我将name1 更改为name111 并按下提交按钮,我会在警报窗口中看到name1。如果使用this.myForm.controls["name"].value,它会返回最后更改的值,但它不正确,因为我可以按下另一个项目的保存按钮。

如何在提交事件中获取当前项目的输入字段的所有值?(包括更改的值)

https://stackblitz.com/edit/angular-3xjnjv?file=src%2Fapp%2Fapp.component.ts

示例:

1) 我明白了

id1 |名称 = 名称 1 |保存按钮1

id2 |名称 = 名称2 |保存按钮2

id3 |名称 = 名称 3 |保存按钮3

2) 我改变了

id1 |名称 = 更改名称1 |保存按钮1

id2 |名称 = 更改名称2 |保存按钮2

id3 |名称 = 更改名称3 |保存按钮3

3) 我按下保存按钮2

4)我看到item: changedname2

onSubmit() {
window.alert("item: " + this.selItem.name);  //  item: changedname2   
}

app.component.html

<form [formGroup]="myForm" (ngSubmit)="onSubmit()">
  <mat-expansion-panel [expanded]="isFirst" *ngFor="let item of items; let isFirst = first; let i = index;">
  <mat-expansion-panel-header>
    <mat-panel-title>
      <h3>{{item.id}}</h3>
    </mat-panel-title>
    <mat-panel-description>
      This is a summary of the content
    </mat-panel-description>
  </mat-expansion-panel-header>

         <div class="row">
            <div>
                <input matInput formControlName="id" value="{{item.id}}" placeholder="{{id}}" type="text">
            </div>  
         </div>
         <div class="row">
             <div>
                <input matInput formControlName="name" value="{{item.name}}" placeholder="{{name}}">
             </div>
         </div>
         <button (click)="setItem(item)" mat-raised-button >{{updateItem}}</button>
</mat-expansion-panel>
</form>

app.component.ts

import { Component } from '@angular/core';
import { ChangeDetectionStrategy, OnInit, ViewChild } from '@angular/core';
import { Observable  } from 'rxjs/Observable';
import { of  } from 'rxjs/observable/of';
import { map } from 'rxjs/operators';
import { MatSort, Sort } from '@angular/material';
import { MatPaginator, PageEvent } from '@angular/material';
import { fromMatSort, sortRows } from './datasource-utils';
import { fromMatPaginator, paginateRows } from './datasource-utils';
import { FormBuilder, FormGroup, FormArray , Validators } from '@angular/forms';


export interface PeriodicElement {
  id: string;
  name: string;
}

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

updateItem = 'Save';

  myForm: FormGroup;
  items: any;
  selItem: any;

  constructor(private formBuilder: FormBuilder) { }

  onSubmit() {
    window.alert("item: " + this.selItem.name);
    window.alert(this.myForm.controls["name"].value);
    // ...
  }

  ngOnInit() {

    this.myForm = this.formBuilder.group({
        id: [''],
        name: ['']
    }); 

        const ELEMENT_DATA: PeriodicElement[] = [{"id":"id1",
                                                "name":"name1"},
                                                {"id":"id2",
                                                "name":"name2"},
                                                {"id":"id3",
                                                "name":"name3"}
                                                //,...
                                                ];
          this.items = ELEMENT_DATA;       

  }

  setItem(item) {
     this.selItem = item;
  }

}

【问题讨论】:

  • 然后使用valueChanges方法获取当前Item
  • curIdx 是干什么用的
  • 您将输入的值设置为 this.curIdx 和 this.setItem 而不是表单组的 id 和名称您认为它们如何更新
  • 准确定义您的需求,我会尽力帮助您
  • @madhavsai bhushan,谢谢,我会学习 valueChanges 方法。我想在用户按下save 按钮后获取输入字段的所有值。用户可以在任何项目上更改表单上的多个输入字段,但在他按下 save(例如带有 id2 保存按钮的项目)后,我只捕获 id2 项目的值。 curIdx 不是这里的必需品

标签: angular angular-material angular7 ngfor formgroups


【解决方案1】:
HTML file - 

// 1 - add (ngModelChange)="updateName(i)" to the input

<input matInput formControlName="name" value="{{item.name}}" placeholder=" 
{{name}}" (ngModelChange)="updateName(i)">

// 2 - Pass index value through the setItem()

<button (click)="setItem(item, i)" mat-raised-button >{{updateItem}} 
</button>


.ts File

// 1 - declare index in AppComponent Class

    updateItem = 'Save';
    myForm: FormGroup;
    items: any;
    selItem: any;
    index: number;      // <----------index

// 2 - Add "updateName(i)" and Update "setItem() && onSubmit()" functions

 onSubmit() {
   alert(this.items[this.index].name);
 }

updateName(i) {
   this.items[i].name = this.myForm.controls["name"].value;
}

setItem(item, i) {       // <----------- (item, i)
  this.selItem = item;
  this.index = i;
}

【讨论】:

  • 不幸的是,它返回最后更改的项目名称。如果您没有更改项目,警报窗口将显示“未定义”。如果您使用id2 更改项目,然后按下带有id3 的项目上的按钮,您会看到带有id2 的项目名称,但它应该是name3
  • 我已经编辑了代码,现在可以正常工作了。试试这个,如果你还有问题,请告诉我!!
【解决方案2】:

解决办法是

Dynamic form using *ngFor and submitting values from it

https://stackblitz.com/edit/angular-t5kbob?file=src%2Fapp%2Fapp.component.ts

app.component.html

<form id="myForm" [formGroup]="thisIsMyForm">
    <div [formArrayName]="'formArrayName'">
        <mat-card *ngFor="let x of data; let i = index">
            <div [formGroupName]="i">
                <mat-form-field>
                    <label>id:</label>
      <input formControlName="id" id="{{x.id}}" matInput value="{{x.id}}">
    </mat-form-field>
    <mat-form-field>
      <label>name:</label>
      <input formControlName="name" id="{{x.name}}" matInput value="{{x.name}}"/>
    </mat-form-field>
    <button *ngIf="fomrControlState(i)" (click)="toggleEdit(i)">Enable Edit</button>
    <button *ngIf="!fomrControlState(i)" (click)="toggleEdit(i)">Save</button>
     </div>
  </mat-card>
  <button [disabled]="thisIsMyForm.get('formArrayName').enabled" (click)="onSubmit()">Submit Form</button>
  </div>
</form>

app.component.ts

import { Component, ViewChild } from '@angular/core';
import { MatSnackBar } from '@angular/material';
import { FormArray, FormBuilder, FormGroup, Validators, FormControl } from '@angular/forms';

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

  thisIsMyForm: FormGroup;

  data = [
    { id: "one", name: "one" },
    { id: "two", name: "two" },
    { id: "three", name: "three" }
  ];

  constructor(private formBuilder: FormBuilder) {
    this.thisIsMyForm = new FormGroup({
      formArrayName: this.formBuilder.array([])
    })

    this.buildForm();
  }

  buildForm() {
    const controlArray = this.thisIsMyForm.get('formArrayName') as FormArray;

    Object.keys(this.data).forEach((i) => {
      controlArray.push(
        this.formBuilder.group({
          id: new FormControl({ value: this.data[i].id, disabled: false }),
          name: new FormControl({ value: this.data[i].name, disabled: false })
        })
      )
    })

    console.log(controlArray.controls)
  }

  toggleEdit(i) {
    const controlArray = this.thisIsMyForm.get('formArrayName') as FormArray;
    console.log(controlArray.controls[i].value)
  }

  fomrControlState(i){
     const controlArray = this.thisIsMyForm.get('formArrayName') as FormArray;
     return controlArray.controls[i].enabled
  }

  onSubmit() {
    // Here I would like to be able to access the values of the 'forms'
    console.log(this.thisIsMyForm.value)
  }

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-15
    • 1970-01-01
    • 1970-01-01
    • 2019-03-25
    • 2013-12-24
    • 1970-01-01
    相关资源
    最近更新 更多