【问题标题】:How to access dropdown selected item properties using angular 7 reactive form如何使用 Angular 7 反应形式访问下拉选定项目属性
【发布时间】:2019-06-18 15:45:24
【问题描述】:

在以下示例中,我有一个包含客户列表的简单下拉列表。当您从下拉列表中选择客户时,我需要完成以下操作。

  1. 所选客户名称应显示在 "txtCustomerName" 文本框中。
  2. 选定的客户名称应显示在 "spnCustomerId" 跨度元素中(我已经以某种方式完成了它,我想确保我使用 "spnCustomerId" strong>反应形式)。

除了上述之外,我在加载页面时收到"ERROR TypeError: control.registerOnChange is not a function" 错误。我在 stackoverflow 上发现了类似的帖子,但我找不到我所面临的问题的可靠答案。

ERROR TypeError: control.registerOnChange is not a function

ERROR TypeError: control.registerOnChange is not a function --> formControlName

我的组件类是这样的

import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder } from '@angular/forms';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  public myForm: FormGroup;
  public allCustomers: Customer[] = new Array();

  constructor(private formBuilder: FormBuilder) {}

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

    this.allCustomers.push(new Customer(0, "John"));
    this.allCustomers.push(new Customer(1, "Kumar"));
    this.allCustomers.push(new Customer(2, "Warma"));
    this.allCustomers.push(new Customer(3, "Sabitha"));
  }

  changeCustomer(e) {
    console.log(JSON.stringify(this.myForm.get('selectedCustomer').value));
  }
}

export class Customer {
  public id: number;
  public name: string;

  constructor(cusId: number, cusName: string) {
    this.id = cusId;
    this.name = cusName;
  }
}

我的html页面是这样的

<form name="frmMain" [formGroup]="myForm">
  <div>
    <div>
      All customers:
      <select (change)="changeCustomer($event)" formControlName="selectedCustomer">
        <option value="" disabled>Please select</option>
        <option *ngFor="let cus of allCustomers" [ngValue]="cus">{{cus.name}}</option>
      </select>
    </div>
    <br/>
    <div>
      Selected customer id :
      <span id="spnCustomerId">{{myForm.get('selectedCustomer').value.id}}</span>
    </div>
    <div>
      Selected customer name :
      <!-- I need to show selected customer name in below text box -->
      <input id="txtCustomerName" type="text"/>
    </div>
  </div>
</form>

请看上面stackblitz的例子

【问题讨论】:

  • 拜托,看看我的回答,问题不是别人的问题

标签: angular angular7 angular-reactive-forms angular8


【解决方案1】:

对不起,答案不正确。见forked stackblitz

你对 Angular 说 selectedCustomer 是一个 FormGroup

selectedCustomer: this.formBuilder.group({
        id: [],
        name:['']
      })

但是当你使用 select 时,你试图给 FormGroup 一个对象作为值

<select (change)="changeCustomer($event)" formControlName="selectedCustomer">
        <option value="" disabled>Please select</option>
        <option *ngFor="let cus of allCustomers" 
             [ngValue]="cus">{{cus.name}}</option>
</select>

这是因为你有错误。

解决办法是selectedCustomer是一个对象,不是FormGroup,是的,FormControl可以存储一个对象,而不仅仅是字符串或者数字

this.myForm = this.formBuilder.group({
      selectedCustomer: []
    }) 

当然,使用安全运算符显示“名称”和“ID”时要小心,因为可以为空

<span id="spnCustomerId">{{myForm.get('selectedCustomer').value?.id}}</span>

【讨论】:

    【解决方案2】:

    发生错误是因为您正在使用 FormBuilder 初始化表单,但并非所有控件都存在于模板中(请参阅此处link)。

    试试这个:

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

    您可以直接订阅formControl,而不是添加更改侦听器,如下所示:

    this.myForm.get('selectedCustomer').valueChanges
      .subscribe(e => {
        this.myForm.get('name').setValue(e.name);
        })
    

    在模板中:

    <input id="txtCustomerName" type="text" formControlName="name"/>
    

    【讨论】:

    • 对不起,@riondo,我不能接受你的回答,可以,答案是其他
    • @riorudo,首先感谢您的解决方案,非常感谢您的帮助。如果不添加名为 "name: ['']" 的单独表单控件,是否有办法使用“selectedCustomer”formControl 获取客户名称?
    • 你可以像 Eliseo 的例子那样做,并将值绑定到 ngModel: 然后你可以从 myForm 中删除 "name" as formControl。
    【解决方案3】:

    试试这样:

    TS:

    this.myForm = this.formBuilder.group({
      selectedCustomer: [],
      selectedCustomerName : []
    })
    
    
    changeCustomer(e) {
        console.log(JSON.stringify(this.myForm.get('selectedCustomer').value));
        let name = (this.myForm.get('selectedCustomer').value).name
    
        this.myForm.patchValue({
          selectedCustomerName : name
        });
      }
    

    模板:

    <div>
      Selected customer id :
      <span id="spnCustomerId">{{myForm.get('selectedCustomer').value?.id}}</span>
    </div>
    <input id="txtCustomerName" type="text" formControlName="selectedCustomerName"/>
    

    【讨论】:

    • 您不需要向您的 formGroup 添加新属性,这不是问题
    • @Adrita Sharma,谢谢您的回答。但是您的解决方案仍然给我提到的错误(“control.registerOnChange 不是函数”)。此外,如果不添加名为 "selectedCustomerName : ['']" 的单独表单控件,是否有办法使用“selectedCustomer”formControl 获取客户名称?
    • @Prabodha 我已经编辑了答案,你不会再收到这个错误了。另外不要忘记在{{myForm.get('selectedCustomer').value?.id}} 中添加 ?
    猜你喜欢
    • 1970-01-01
    • 2019-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-31
    • 2020-04-22
    • 2020-12-16
    相关资源
    最近更新 更多