web-dev-qa-db-ja.com

@ViewChildを使用して入力の.nativeElementを取得すると、「undefined」が返されます

Angular2で次のフォームを作成しました:

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内では、#foobar = "ngForm"から= "ngForm"部分を削除しない限り、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"     #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));
    }
}

つまり、ngFormに関連しない補助ハッシュタグ(#tralala)で入力要素を強化しましたが、このソリューションは機能しますが、小さなハックを適用しているように感じるので、安心しません。テキストボックスのネイティブ要素を、@ ViewChildまたはthis.form.controls(またはその効果のあるもの)を介して、私が使用したような回避策に頼ることなく、よりエレガントで簡単な方法で取得できるはずです。しかし、私は正確にどのように把握することはできません。

クイック補遺:重要な場合は、Angular2 2.0-beta7を使用しています。

11
XDS

別のテンプレート変数を追加するだけです

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

_="ngForm"_を使用すると、テンプレート変数は別の目的を取得し、@ViewChild()では機能しません

それでも機能すると思われる場合は、バグレポートの作成を検討してください。

31