programing

Angular2-구성 요소로드시 텍스트 상자 집중

nasanasas 2020. 11. 16. 21:36
반응형

Angular2-구성 요소로드시 텍스트 상자 집중


Angular2 (Beta 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>


간단한 autofocusHTML5 속성을 사용하면 '로드시'시나리오에서 작동합니다.

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

또는

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

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


이 답변은 Angular 2 게시물에서 영감을 얻었습니다 . 새로 추가 된 입력 요소에 중점을 둡니다.

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>


원래 질문은 이벤트에 대한 응답으로 처음에 포커스를 설정하거나 나중에 포커스를 설정하는 방법을 요청했습니다. 이에 접근하는 올바른 방법은 모든 입력 요소에 대해 설정할 수있는 속성 지시문을 만든 다음 사용자 지정 이벤트를 사용하여이 입력 요소에 대한 포커스 메서드를 안전하게 트리거하는 것 같습니다. 그러려면 먼저 지시문을 작성하십시오.

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를 사용합니다. 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);
}

Don't forget to import EventEmitter above the component like this:

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

and in the template for this component, set the new [focus] attribute like this:

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

Finally, in your module, import and declare the new directive like this:

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

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

To recap: the ngAfterViewInit function will cause the new EventEmitter to emit, and since we assigned this emitter to the [focus] attribute in the input element in our template, and we declared this EventEmitter as an input to the new directive and invoked the focus method in the arrow function that we passed to the subscription to this event, the input element will receive focus after the component is initialized, and whenever setFocus is called.

I had the same need in my own app, and this worked as advertised. Thank you very much to the following: http://blog.thecodecampus.de/angular-2-set-focus-element/


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

this is the best and simplest way, because code "myInput.focus()" runs after input created


See Angular 2: Focus on newly added input element for how to set the focus.

For "on load" use the ngAfterViewInit() lifecycle callback.


I had a slightly different problem. I worked with inputs in a modal and it drove me mad. No of the proposed solutions worked for me.

Until i found this issue: https://github.com/valor-software/ngx-bootstrap/issues/1597

This good guy gave me the hint that ngx-bootstrap modal has a focus configuration. If this configuration is not set to false, the modal will be focused after the animation and there is NO WAY to focus anything else.

Update:

To set this configuration, add the following attribute to the modal div:

[config]="{focus: false}"

Update 2:

To force the focus on the input field i wrote a directive and set the focus in every AfterViewChecked cycle as long as the input field has the class ng-untouched.

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

Also, it can be done dynamically like so...

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

Where input is

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

I didn't have much luck with many of these solutions on all browsers. This is the solution that worked for me.

For router changes:

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

Then ngAfterViewInit() for the onload scenario.

참고URL : https://stackoverflow.com/questions/35790021/angular2-focusing-a-textbox-on-component-load

반응형