【问题标题】:How to get formControlName Programmatically in Angular 5 or above如何在 Angular 5 或更高版本中以编程方式获取 formControlName
【发布时间】:2018-11-11 01:44:03
【问题描述】:

需要知道,当您在一个表单中有多个控件并且您想知道用户更改了哪个控件以便您可以采取一些操作时。

<input formControlName="item_name" #itemName (input)="inputChanged(itemName)">

为什么我需要获取 formControlName?

正如您在图片中看到的那样,某些字段已被编辑但未确认,这就是为什么用户会看到用于验证或取消对该特定字段的操作的选项。这就是为什么我需要获取输入更改字段的formControlName 以便我可以仅显示该字段的选项。

我已经搜索了它的解决方案,但在 stack-overflow 上找不到,所以我决定发布这个问题并附上答案

【问题讨论】:

  • 为什么不能将名称作为字符串传递给inputChanged("item_name")
  • 当你有多个控件并且你想获取输入已经改变的控件名称时。
  • 您为什么需要(输入)控件?他们的目的是避免这样的事情。

标签: angular angular5 angular-reactive-forms angular6 reactive-forms


【解决方案1】:

像 FormGroup 和 FormControl 这样的响应式表单实例有一个 valueChanges 方法,该方法返回一个发出最新值的 observable。因此,您可以订阅 valueChanges 来更新实例变量或执行操作。

例子

myForm: FormGroup;
formattedMessage: string;

constructor(private formBuilder: FormBuilder) {}

ngOnInit() {
  this.myForm = this.formBuilder.group({
    name: '',
    email: '',
    message: ''
  });

  this.onChanges();
}

请注意我们在初始化表单后如何在 ngOnInit 生命周期钩子中调用 onChanges 方法。这是我们的 onChanges 方法的内容:

onChanges(): void {
  this.myForm.valueChanges.subscribe(val => {
    this.formattedMessage =
    `Hello,

    My name is ${val.name} and my email is ${val.email}.

    I would like to tell you that ${val.message}.`;
  });
}

您还可以侦听特定表单控件而不是整个表单组的更改:

onChanges(): void {
  this.myForm.get('name').valueChanges.subscribe(val => {
    this.formattedMessage = `My name is ${val}.`;
  });
}

【讨论】:

    【解决方案2】:

    您可以使用该方法:

    <input formControlName="item_name" #itemName (change)="inputChanged($event)">
    

    当输入值改变时,改变事件发生,Angular 在 $event 变量中提供了一个对应的 DOM 事件对象,这段代码将其作为参数传递给组件的 inputChanged() 方法。

    inputChanged (event: any) { // without type info
    this.myValue = event.target.value;
      }
    }
    

    参考链接: https://angular.io/guide/user-input

    另一种更优雅的选择:

    模板

    <form [formGroup]="usersForm">
      <input type="text" formControlName="name" placeholder="name"/>
    </form>
    

    组件类

    export class AppComponent implements OnInit, OnDestroy {
      usersForm: FormGroup;
      message: string;
    
      private subscriptions$ = new Subscription();
    
      constructor( private formBuilder: FormBuilder) {}
    
      ngOnInit(): void {
        this.usersForm = this.formBuilder.group({
          name: '',
          age: '',
          gender: '',
        });
    
        this.subscriptions$.add(this.name.valueChanges.subscribe(value => {
          // Do someting
        }));
      }
    
      ngOnDestroy(): void {
        this.subscriptions$.unsubscribe();
      }
    
      get name(): AbstractControl {
        return this.usersForm.get('name');
      }
    }
    

    查看 Stackbliz 中的完整示例:
    https://stackblitz.com/edit/form-builder-example

    【讨论】:

    • 我要获取formControlName。有没有办法进入函数“inputChanged”?
    • 如果你看到了,我正在使用“AbstractControl”类中的“valueChanges”Observable。这个 Observable 返回值;
    • 通过这种方法,您可以准确地知道哪个控件发生了变化。
    【解决方案3】:

    我发现的最直接的方式:

    HTML:

    <input formControlName="item_name" (input)="inputChanged($event)">
    

    TS:

    inputChanged(e) {
      log(e.target.getAttribute('formControlName')) // item_name 
    }
    

    无需在每个输入中添加id。只需将$event 作为参数传递即可。

    【讨论】:

    • 不确定是否是 Angular 版本的问题。我正在使用 Angular 9.2。我找不到属性formControlName,但是有一个属性ng-reflect-name,好像设置为fromControlName
    【解决方案4】:

    从此输入字段中获取formControlName

    <input formControlName="item_name" #itemName (input)="inputChanged(itemName)">
    

    只需要获取属性formControlName

    inputChanged(element: HTMLElement) {
      log(element.getAttribute('formControlName')) // item_name 
    }
    

    【讨论】:

    • 使用模板引用变量是匹配简单 src 事件 html 技术的最简单解决方案。 angular.io/guide/template-syntax#ref-vars
    • 注意:请注意,当您将formControlName 设置为模板变量时,您将没有formControlName 属性,例如[formControlName]="xyz"。确实花了我一些时间和头痛来弄清楚。
    【解决方案5】:

    您可以使用 ElementRef 获取 formControlName 属性

    HTML 代码

     <input formControlName="item_name" #itemName>
    

    组件类文件

    import {Component, ElementRef, OnInit, ViewChild} from '@angular/core';
    
    export class AppComponent implements OnInit { 
    
        // itemName name is reference variable #itemName
    
        @ViewChild('itemName') itemName: ElementRef;
    
        ngOnInit() {
            this.itemName.nativeElement.getAttribute('formControlName');
        }
    }
    

    获取 formControllName 的更改值

    <input type="text" formControlName="item_name" #itemName (input)="inputChanged($event.target.value)">
    
       export class AppComponent {
        inputChanged(searchValue: string) {
        console.log(searchValue);
        }
    }
    

    【讨论】:

      【解决方案6】:

      如果您使用的是响应式表单,那么您可以在 Component TS 中创建表单,而不是在组件模板中声明 formControlName,如下所示:

       this.myForm= this.formBuilder.group({
            'item_name' : [null, Validators.compose([Validators.required])]
          });
      

      此外,响应式表单不是通过事件处理输入更改,而是通过在表单字段上注册“value_changes”为您提供处理输入值更改的权限,如下所示:

      this.myForm.get('item_name').valueChanges.subscribe(val => {
          this.formattedMessage = `My name is ${val}.`;
        });
      

      通过这种方式,您始终使用组件 TS 定义中的反应式表单组中定义的 formControlName

      在组件模板中使用如下:

      <input formControlName="item_name" />
      

      【讨论】:

      • 你的方法在我看来不错。请分享详细的文档或视频链接。
      • 是的,您可以在以下链接中找到详细文档:angular.io/guide/reactive-forms
      【解决方案7】:

      如果你使用的是 Angular Reactive Forms,你可以使用类似这样的东西

      为您的 HTML 输入

      <input formControlName="item_name" #itemName (change)="inputChanged()">
      

      为你的组件

      import { Component, OnInit } from '@angular/core';
      import { FormBuilder, FormGroup, Validators } from '@angular/forms';
      
      formName: FormGroup;
      myValue: string;
      
      constructor(private formBuilder: FormBuilder) {}
      
      ngOnInit() {
          this.formName = this.formBuilder.group({
            'item_name' : [null, Validators.compose([Validators.required])]
          });
      
          window.scroll(0,0);
      }
      
      inputChanged(){
          this.myValue = this.formName.get('item_name').value;
      }
      

      参考链接: https://angular.io/guide/form-validation

      【讨论】:

        猜你喜欢
        • 2010-09-08
        • 2021-08-05
        • 2021-08-20
        • 1970-01-01
        • 2010-10-30
        • 2016-09-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多