2016-04-18 6 views
4
<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 выше, как получить ссылку на ионном вход, так что я могу setFocus() на него после того, как проверка не пройдена. Я уже вышел с кодом ниже для проверки каждого входа.Угловое 2 - Доступ/получить входной элемент внутри * ngFor и ngModel

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?

+0

ли это решить проблему? –

ответ

7

Подход получить ссылки элементов, созданных с *ngFor является @ViewChildren()

Если элементы на самом деле являются компонентами или директив, то компонент/директивой типа может быть передан в качестве параметра в противном случае переменная шаблона может быть добавлена ​​и именем переменная шаблона (как строка) может использоваться для запроса элементов.

В этом случае как переменная шаблона и тип компоненты возвращают экземпляр компонента, но называть фокус нам нужны ElementRef.nativeElement поэтому я создал вспомогательную директиву, которая применяется к ion-input и используются для запроса элементов, а также для вызова 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: Focus on newly added input element

Plunker example

+2

На самом деле все было не так просто. Я создал пример [** Plunker **] (https://plnkr.co/edit/JUMdao?p=preview). –

+0

Прохладный раствор, Гюнтер! Я думал, что могу что-то сделать с помощью элементов управления формой ... –

Смежные вопросы