81

Angular2 (ベータ 8) でコンポーネントを開発しています。コンポーネントにはテキストボックスとドロップダウンがあります。コンポーネントが読み込まれるか、ドロップダウンの変更イベントが発生するとすぐに、テキストボックスにフォーカスを設定したいと思います。angular2でこれをどのように達成しますか。以下は、コンポーネントの Html です。

<div>
    <form role="form" class="form-horizontal ">        
        <div [ngClass]="{showElement:IsEditMode, hidden:!IsEditMode}">
            <div class="form-group">
                <label class="control-label col-md-1 col-sm-1" for="name">Name</label>
                <div class="col-md-7 col-sm-7">
                    <input id="name" type="text" [(ngModel)]="person.Name" class="form-control" />

                </div>
                <div class="col-md-2 col-sm-2">
                    <input type="button" value="Add" (click)="AddPerson()" class="btn btn-primary" />
                </div>
            </div>
        </div>
        <div [ngClass]="{showElement:!IsEditMode, hidden:IsEditMode}">
            <div class="form-group">
                <label class="control-label col-md-1 col-sm-1" for="name">Person</label>
                <div class="col-md-7 col-sm-7">
                    <select [(ngModel)]="SelectedPerson.Id"  (change)="PersonSelected($event.target.value)" class="form-control">
                        <option *ngFor="#item of PeopleList" value="{{item.Id}}">{{item.Name}}</option>
                    </select>
                </div>
            </div>
        </div>        
    </form>
</div>

4

10 に答える 10

80

この回答は、投稿Angular 2: Focus on new added input element に触発されて います

Angular2 で Html 要素にフォーカスを設定する手順

  1. コンポーネントに ViewChildren をインポートする

    import { Input, Output, AfterContentInit, ContentChild,AfterViewInit, ViewChild, ViewChildren } from 'angular2/core';
    
  2. フォーカスを設定する html のローカル テンプレート変数名を宣言します。

  3. 関数 ngAfterViewInit() またはその他の適切なライフサイクル フックを実装します。
  4. 以下は、フォーカスを設定するために使用したコードです

    ngAfterViewInit() {vc.first.nativeElement.focus()}
    
  5. #inputアクセスしたい DOM 要素に属性を追加します。

///This is typescript
import {Component, Input, Output, AfterContentInit, ContentChild,
  AfterViewChecked, AfterViewInit, ViewChild,ViewChildren} from 'angular2/core';

export class AppComponent implements AfterViewInit,AfterViewChecked { 
   @ViewChildren('input') vc;
  
   ngAfterViewInit() {            
        this.vc.first.nativeElement.focus();
    }
  
 }
<div>
    <form role="form" class="form-horizontal ">        
        <div [ngClass]="{showElement:IsEditMode, hidden:!IsEditMode}">
            <div class="form-group">
                <label class="control-label col-md-1 col-sm-1" for="name">Name</label>
                <div class="col-md-7 col-sm-7">
                    <input #input id="name" type="text" [(ngModel)]="person.Name" class="form-control" />

                </div>
                <div class="col-md-2 col-sm-2">
                    <input type="button" value="Add" (click)="AddPerson()" class="btn btn-primary" />
                </div>
            </div>
        </div>
        <div [ngClass]="{showElement:!IsEditMode, hidden:IsEditMode}">
            <div class="form-group">
                <label class="control-label col-md-1 col-sm-1" for="name">Person</label>
                <div class="col-md-7 col-sm-7">
                    <select [(ngModel)]="SelectedPerson.Id"  (change)="PersonSelected($event.target.value)" class="form-control">
                        <option *ngFor="#item of PeopleList" value="{{item.Id}}">{{item.Name}}</option>
                    </select>
                </div>
            </div>
        </div>        
    </form>
</div>

于 2016-03-04T10:07:11.783 に答える
29

元の質問では、イベントに応じて、最初にフォーカスを設定する方法、または後でフォーカスを設定する方法を求めていました。これにアプローチする正しい方法は、任意の入力要素に設定できる属性ディレクティブを作成し、カスタム イベントを使用して、この入力要素でフォーカス メソッドを安全にトリガーすることです。そのためには、まずディレクティブを作成します。

import { Directive, Input, EventEmitter, ElementRef, Renderer, Inject } from '@angular/core';

@Directive({
    selector: '[focus]'
})
export class FocusDirective {
    @Input('focus') focusEvent: EventEmitter<boolean>;

    constructor(@Inject(ElementRef) private element: ElementRef, private renderer: Renderer) {
    }

    ngOnInit() {
        this.focusEvent.subscribe(event => {
            this.renderer.invokeElementMethod(this.element.nativeElement, 'focus', []);
        });
    }
}

これは、Web ワーカーに対して安全な、nativeElement で renderer.invokeElementMethod を使用することに注意してください。focusEvent が入力として宣言されていることにも注意してください。

次に、新しいディレクティブを使用して入力要素にフォーカスを設定するテンプレートを持つ Angular 2 コンポーネントに次の宣言を追加します。

public focusSettingEventEmitter = new EventEmitter<boolean>();

ngAfterViewInit() { // ngOnInit is NOT the right lifecycle event for this.
    this.focusSettingEventEmitter.emit(true);
}
setFocus(): void {
  this.focusSettingEventEmitter.emit(true);
}

次のように、コンポーネントの上に EventEmitter をインポートすることを忘れないでください。

import { Component, EventEmitter } from '@angular/core';

このコンポーネントのテンプレートで、新しい [focus] 属性を次のように設定します。

<input id="name" type="text" name="name" 
    [(ngModel)]="person.Name" class="form-control"
    [focus]="focusSettingEventEmitter">

最後に、モジュールで、次のように新しいディレクティブをインポートして宣言します。

import { FocusDirective } from './focus.directive';

@NgModule({
    imports: [ BrowserModule, FormsModule ],
    declarations: [AppComponent, AnotherComponent, FocusDirective ],
    bootstrap: [ AppComponent ]
})

要約すると、ngAfterViewInit 関数は新しい EventEmitter を発行させます。このエミッターをテンプレートの入力要素の [focus] 属性に割り当てたため、この EventEmitter を新しいディレクティブへの入力として宣言し、フォーカスを呼び出しました。このイベントへのサブスクリプションに渡したアロー関数のメソッドを使用すると、入力要素は、コンポーネントが初期化された後、および setFocus が呼び出されるたびにフォーカスを受け取ります。

私自身のアプリでも同じニーズがありましたが、これは宣伝どおりに機能しました。以下に感謝します: http://blog.thecodecampus.de/angular-2-set-focus-element/

于 2016-11-12T21:50:02.607 に答える
6

フォーカスを設定する方法については、 Angular 2: 新しく追加された入力要素にフォーカスするを参照してください。

「ロード中」の場合は、ngAfterViewInit()ライフサイクル コールバックを使用します。

于 2016-03-04T07:16:02.667 に答える