Angular 2 - 访问/获取 *ngFor 和 ngModel 中的输入元素 [英] Angular 2 - Access/get the input element inside an *ngFor and ngModel

查看:13
本文介绍了Angular 2 - 访问/获取 *ngFor 和 ngModel 中的输入元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

<ion-card *ngFor='#product of products | mapToIterable:"key":true'>
    <ion-list>
        <ion-item>
            <ion-label stacked>Account No. / Phone No.</ion-label>
            <ion-input type="text" [(ngModel)]="product.msisdn"></ion-input>
        </ion-item>
        <ion-item>
            <ion-label stacked>Amount</ion-label>
            <ion-input type="text" (keypress)="isNumberKey($event)" [(ngModel)]="product.amount"></ion-input>
        </ion-item>
    </ion-list>
</ion-card>

参考上面的html,如何获取ion-input的引用,以便验证失败后可以setFocus()对其进行setFocus().我已经用下面的代码来验证每个输入.

Referring to the html above, how do I get the reference of ion-input so that I can setFocus() on it after validation fails. I've already came out with the code below to validate each inputs.

for (var product of <any>this.products) {
    if (product.service_type_id == 2 && !product.msisdn) {
        alert('something');
        //Get the element and set focus here.
    }
}

这是一个好方法吗?在 Angular 2 中有没有更好的方法来处理这个问题?

Is this a good approach? Is there a better way of handling this in Angular 2?

推荐答案

获取使用 *ngFor 创建的元素的引用的方法是 @ViewChildren()

An approach to get references of elements created with *ngFor is @ViewChildren()

如果元素实际上是组件或指令,则可以将组件/指令类型作为参数传递,否则可以添加模板变量,并且可以使用模板变量的名称(作为字符串)来查询元素.

If the elements are actually components or directives then the component/directive type can be passed as parameter otherwise a template variable can be added and the name of the template variable (as string) can be used to query the elements.

在这种情况下,模板变量和组件类型都返回组件实例,但要调用焦点,我们需要 ElementRef.nativeElement 因此我创建了一个应用于 ion- 的辅助指令input 用于查询元素,也用于调用focus():

In this case both a template variable and the component type return the component instance but to call focus we need the ElementRef.nativeElement therefore I created a helper directive that is applied to ion-input and is used to query the elements and also to call focus():

import {Component, Directive, Renderer, HostListener, ViewChildren, ElementRef} from 'angular2/core'

/// Helper directive
@Directive({
  selector: 'ion-input'
})
class Focusable {
  constructor(public renderer: Renderer, public elementRef: ElementRef) {}

  focus() {
    console.debug(this.elementRef.nativeElement);
    this.renderer.invokeElementMethod(
        this.elementRef.nativeElement, 'focus', []);
  }
}

/// Test component instead of the original ion-input
@Component({
    selector: 'ion-input',
    host: {'tabindex': '1'},
    template: `
    <div>input (focused: {{focused}})</div>
    `,
})
export class IonInput {
  focused:boolean = false;

  @HostListener('focus') 
  focus() {
    this.focused = true;
  }
  @HostListener('blur') 
  blur() {
    this.focused = false;
  }
}

/// Queries the elements and calls focus
@Component({
    selector: 'my-app',
    directives: [IonInput, Focusable],
    template: `
    <h1>Hello</h1>
<div *ngFor="let product of products">
  <ion-input #input type="text"></ion-input>
</div>   
<button *ngFor="let product of products; let index=index" (click)="setFocus(index)">set focus</button>
    `,
})
export class AppComponent {
  constructor(private renderer:Renderer) {
    console.debug(this.renderer)
  }

  products = ['a', 'b', 'c']
  @ViewChildren(Focusable) inputs;

  ngAfterViewInit() {
    // `inputs` is now initialized
    // iterate the elements to find the desired one
  }

  setFocus(index) {
    // `inputs` is now initialized
    // iterate the elements to find the desired one
    //var input = ...
    //console.debug(this.inputs.toArray()[1]);
    this.inputs.toArray()[index].focus();
  }  
}

另请参阅Angular 2:关注新添加的输入元素

Plunker 示例

这篇关于Angular 2 - 访问/获取 *ngFor 和 ngModel 中的输入元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆