web-dev-qa-db-ja.com

Angular2 - テキストボックスをコンポーネントのロードにフォーカスする

Angular 2(Beta 8)でコンポーネントを開発しています。コンポーネントにはテキストボックスとドロップダウンがあります。コンポーネントがロードされたらすぐに、またはドロップダウンの変更イベントが発生したら、テキストボックスにフォーカスを置きたいどのように角度2でこれを達成するでしょう。以下はコンポーネントの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>
63
parag

この答えはpost からヒントを得たものです。Angular 2:新しく追加された入力要素に焦点を当てます

Angular 2で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. アクセスしたいDOM要素に#input属性を追加します。

///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>
60
parag

単純なautofocus HTML5属性を使用すると 'on load'シナリオで動作します

 <input autofocus placeholder="enter text" [(ngModel)]="test">

または

<button autofocus (click)="submit()">Submit</button>

http://www.w3schools.com/TAgs/att_input_autofocus.asp

63
Nikhil Nambiar

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

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', []);
        });
    }
}

NativeElementでrenderer.invokeElementMethodを使用することに注意してください。これはWebワーカーにとって安全です。 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を発生させます、そしてこのエミッタをテンプレートのinput要素の[focus]属性に割り当て、そしてこのEventEmitterを新しいディレクティブへの入力として宣言し、フォーカスを呼び出しました。このイベントのサブスクリプションに渡したarrow関数のメソッドでは、input要素は、コンポーネントが初期化された後、およびsetFocusが呼び出されるたびにフォーカスを受け取ります。

私は自分のアプリにも同じニーズがあり、これは宣伝どおりに機能しました。次のことをどうもありがとうございました。 http://blog.thecodecampus.de/angular-2-set-focus-element/

24
Kent Weigel
<input id="name" type="text" #myInput />
{{ myInput.focus() }}

コード "myInput.focus()"は、入力が作成された後に実行されるため、これが最も簡単で簡単な方法です。

18
Sergey Gurin

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

"on load"の場合はngAfterViewInit()ライフサイクルコールバックを使用してください。

4

少し違う問題がありました。私はモーダルで入力を処理しました、そしてそれは私を怒らせました。提案された解決策のどれも私のために働きませんでした。

私はこの問題を見つけるまで: https://github.com/valor-software/ngx-bootstrap/issues/1597

この親切な人は、ngx-bootstrap modalにフォーカス設定があるというヒントを私にくれました。この設定がfalseに設定されていない場合、モーダルはアニメーションの後にフォーカスされ、それ以外にフォーカスする方法はありません。

更新:

この構成を設定するには、モーダルdivに次の属性を追加します。

[config]="{focus: false}"

アップデート2:

入力フィールドにフォーカスを強制するために、私はディレクティブを書き、入力フィールドがクラスng-untouchedである限り、すべてのAfterViewCheckedサイクルでフォーカスを設定します。

 ngAfterViewChecked() {
    // This dirty hack is needed to force focus on an input element of a modal.
    if (this.el.nativeElement.classList.contains('ng-untouched')) {
        this.renderer.invokeElementMethod(this.el.nativeElement, 'focus', []);
    }
}
2
FireGnome

また、それはそう動的に行うことができます...

<input [id]="input.id" [type]="input.type" [autofocus]="input.autofocus" />

入力があるところ

const input = {
  id: "my-input",
  type: "text",
  autofocus: true
};
1
SoEzPz

私はすべてのブラウザでこれらの解決策の多くにあまり運がありませんでした。これは私のために働いた解決策です。

ルータを変更する場合

router.events.subscribe((val) => {
    setTimeout(() => {
        if (this.searchElement) {
            this.searchElement.nativeElement.focus();
        }
    }, 1);
})

それからonloadシナリオのためのngAfterViewInit()

0
rtaft