2016-10-29 8 views
7

Я создал следующий вид angular2:Использование @ViewChild, чтобы разжиться .nativeElement входного возвращает «неопределенное»

import {Component, ElementRef, ViewChild, AfterViewInit} from "angular2/core"; 
import {Observable} from "rxjs/Rx"; 
import {ControlGroup, Control, Validators, FormBuilder} from "angular2/common"; 

@Component({ 
    selector: "ping-pong", 
    template: ` 
        <form 
        name="someform"        [ngFormModel]="form"> 
         <div class="form-group"> 
          <input         
           id="foobar"      #foobar="ngForm" <-- without ="ngForm" everything works fine 
           type="text"      ngControl="foobar" 
           value="" 
           class="form-control" 
          /> 
         </div> 
        </form> 
       `, 
    styles: [` 
        form { 
         width: 300px; 
        } 
       `] 
}) 

export class ChangepswdFormComponent implements AfterViewInit { 
    @ViewChild("foobar") foobar: ElementRef; 
    private form: ControlGroup; 

    public constructor(formBuilder: FormBuilder) { 
     this.form = formBuilder.group({ 
      foobar: [""] 
     }); 
    } 

    public ngAfterViewInit(): void { 
     console.log(this.foobar.nativeElement); 
     //observable doesnt work because nativeelement is undefined 
     //Observable.fromEvent(this.foobar.nativeElement, "keyup").subscribe(data => console.log(data)); 
    } 
} 

Внутри ngAfterViewInit бит nativeElement не определен, если я не удалить = «ngForm» часть из #foobar = «ngForm» .I преодолели эту проблему, сделав следующие настройки:

import {Component, ElementRef, ViewChild, AfterViewInit} from "angular2/core"; 
import {Observable} from "rxjs/Rx"; 
import {ControlGroup, Control, Validators, FormBuilder} from "angular2/common"; 

@Component({ 
    selector: "ping-pong", 
    template: ` 
        <form 
        name="someform"        [ngFormModel]="form"> 
         <div class="form-group"> 
          <input         
           id="foobar"      #foobar="ngForm"  #tralala 
           type="text"      ngControl="foobar" 
           value="" 
           class="form-control" 
          /> 
         </div> 
        </form> 
       `, 
    styles: [` 
        form { 
         width: 300px; 
        } 
       `] 
}) 

export class ChangepswdFormComponent implements AfterViewInit { 
    @ViewChild("tralala") foobar: ElementRef; 
    private form: ControlGroup; 

    public constructor(formBuilder: FormBuilder) { 
     this.form = formBuilder.group({ 
      foobar: [""] 
     }); 
    } 

    public ngAfterViewInit(): void { 
     console.log(this.foobar.nativeElement); 
     let keyups = Observable.fromEvent(this.foobar.nativeElement, "keyup"); 
     keyups.subscribe(data => console.log(data)); 
    } 
} 

другими словами я обогащены входной элемент с Auxilary хэштегом (#tralala), которая не связана с ngForm.Even хотя это решение работает, я не чувствую себя непринужденно, потому что он чувствует например, я применяю небольшой взлом. Мы должны каким-то образом восстановить собственный элемент текстового поля более элегантным/простым способом либо через @ViewChild, либо через this.form.controls (или что-то в этом роде) БЕЗ использования обходных решений, подобных тому, которое я использовал. Но я не могу понять, как именно.

Quick Addend: Я использую Angular2 2.0-beta7, если это имеет значение.

ответ

15

Просто добавьте еще одну переменную шаблона

#foobar="ngForm" #foobarElement 
@ViewChild("foobarElement") foobar: ElementRef; 

С ="ngForm" переменная шаблона получает различные цели и не работает с @ViewChild()

Если вы думаете, это должно работать, рассмотреть создавая отчет об ошибке.

+0

Спасибо за настройку. Как я уже говорил, я пробовал этот подход, и он действительно работал. Однако (как уже было сказано) я нахожу подход немного ... контринтуитивным. – xDisruptor

+0

Что вам ожидать от '@ViewChild()' в этом случае? Элемент, в который добавлена ​​переменная шаблона (''), директиве или 'ngForm', которая присваивается переменной? –

+0

У меня есть обновленная формулировка, чтобы подчеркнуть мою цель: «Нам нужно как-то восстановить собственный элемент текстового поля более элегантным/простым способом либо через @ViewChild, либо через this.form.controls (или что-то в этом роде) БЕЗ прибегающих к обходным решениям, подобным тому, который я использовал ». <- Я имею в виду вспомогательный метод вспомогательного тега, который я использовал - только потому, что он работает, это не значит, что это элегантный или «канонический» способ делать вещи в Angular2 (да, я знаю, что я перфекционист :)) – xDisruptor