简体   繁体   English

如何从Angular 4+中的NgForm中的NgModel FormControl获取ElementRef引用

[英]How to get ElementRef reference from NgModel FormControl in NgForm in Angular 4+

In Angular 4+, I've following template driven form: 在Angular 4+中,我遵循以下模板驱动形式:

<form #addForm="ngForm" (ngSubmit)="onFormSubmit($event, addForm)" >
  <div class="form-group">
    <label for="item_name">Item Name</label>
    <input id="item_name" name="item_name" [(ngModel)]="itemName" 
          #item_name="ngModel" autofocus class="form-control"
          required minlength="4" maxlength="20" 
          aria-describedby="itemNameHelpBlock">
    <small *ngIf="(item_name.invalid && item_name.touched)" id="itemNameHelpBlock" class="form-text text-error" >
      Value must be at least 4 characters and must not exceed 20 characters
    </small>
  </div>
  <div class="form-group">
    <label for="item_type">Item Type</label>
    <input id="item_type" name="item_type" [(ngModel)]="itemType" 
         #item_type="ngModel" class="form-control" required minlength="2"
          maxlength="20" aria-describedby="itemTypeHelpBlock">
    <small *ngIf="(item_type.invalid && item_type.touched)" id="itemTypeHelpBlock" class="form-text text-error" >
      Value must be at least 2 characters and must not exceed 20 characters
    </small>
  </div>
  <button class="btn btn-output-primary btn-lg" [disabled]="!addForm.form.valid">Add</button>
</form>

In the component section, I want to access the form field (ie item_name , item_type ) as ElementRef so that I can access their corresponding DOM element through the nativeElement method of ElementRef class. 在组件部分,我想以ElementRef的形式访问表单字段(即item_nameitem_type ),以便可以通过ElementRef类的nativeElement方法访问其对应的DOM元素。

I've tried with @ViewChild but, it returns NgModel class object: 我尝试使用@ViewChild但是它返回NgModel类对象:

  @ViewChild('item_name') item_name: ElementRef;

  ngAfterViewInit() {
    console.log(this.item_name); // it returns NgModel class object
  }

But, I need to access the DOM HTMLElement of #item_name form field so that I can reset document focus to #item_name input field after every form submission. 但是,我需要访问#item_name表单字段的DOM HTMLElement ,以便在每次提交表单后可以将文档焦点重置为#item_name输入字段。 Now, I don't know how I can do it without directly accessing the DOM and I don't wanna directly access the DOM via DOM api. 现在,我不知道如何在不直接访问DOM的情况下做到这一点,也不想通过DOM API直接访问DOM。

I would be glad if I get some help here. 如果我在这里得到一些帮助,我将很高兴。

I would simply add read option to ViewChild query: 我只是向ViewChild查询添加read选项:

@ViewChild('item_name', { read: ElementRef }) item_name: ElementRef;
                           ^^^^^^^^^^^^^^^

Stackblitz Example Stackblitz示例

See also 也可以看看

Just to give a use case, you can point #item_name to ngModel to access some attributes of the model itself, for example if it's currently considered valid. 仅给出一个用例,您可以将#item_name指向ngModel来访问模型本身的某些属性,例如,如果当前认为它是有效的。

<input id="item_name" name="item_name" [(ngModel)]="itemName" #item_name="ngModel" 
    autofocus class="form-control">
<!-- here's where you can access the attributes if it's pointed to ngModel-->
<small [hidden]="password.valid">
  The item name is not valid
</small>

If you don't need this rather fancy stuff, you can just remove it, as Andriy proposed. 如果您不需要这些花哨的东西,可以按照Andriy的建议将其删除。 Then it's working out of the box with no further changes. 然后,它可以立即使用,没有任何进一步的更改。

If you need to keep it however, you can give your input field an additional reference which you can use to get the ElementRef. 但是,如果需要保留它,可以为输入字段提供一个附加引用,该引用可用于获取ElementRef。

<input id="item_name" name="item_name" [(ngModel)]="itemName"
   #item_name="ngModel" #itemNameField autofocus class="form-control">

You just have to reference the one that is not pointing to ngModel . 您只需要引用不指向ngModel

@ViewChild('itemNameField') itemNameField: ElementRef;

Angular does not complain about having multiple references on one field (as far as I tested it) Angular并不抱怨在一个字段上有多个引用(据我测试)

In your HTML, do not point template reference #item_name to ngModel , just leave it empty like: 在您的HTML中,不要将模板引用#item_name指向ngModel ,只需将其保留为空,例如:

<div class="form-group">
  <label for="item_name">Item Name</label>
  <input id="item_name" 
         class="form-control"
         name="item_name" 
         [(ngModel)]="itemName" 
         #item_name 
         autofocus>
</div>

then, you can access DOM element using @ViewChild decorator (as you did) like: 然后,您可以使用@ViewChild装饰器(如您所做的那样)访问DOM元素,例如:

this.item_name.nativeElement,

I noticed, you have a typo in your submit button: opening '[' is missing just before disabled property. 我注意到,您的“提交”按钮中有一个错别字:在disabled属性之前,缺少'['。

Plunker: https://plnkr.co/edit/XHqOiEBmuFrA3slZSlrD?p=preview 柱塞: https ://plnkr.co/edit/XHqOiEBmuFrA3slZSlrD p = preview

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM