새로 추가 된 입력 요소에 집중
input
상자 목록이있는 새로운 Angular 2 앱이 있습니다. 사용자가 리턴 키를 누르면 input
현재 편집중인 상자 바로 뒤에 새 상자를 추가합니다 . 또는 (비동기 적으로) 모델의 배열에 새 항목을 추가하여 Angular 2가 input
가까운 장래에 자동으로 새 상자를 생성합니다 .
어떻게이 정도로 할 수 input
초점을 자동으로 새로 추가 된 요소로 변경?
편집 1 :
또는 DOM을 생성하는 모델 객체에 대한 참조를 얻습니다. 컴포넌트 코드에서 특정 모델 객체를 나타내는 DOM 요소를 검색하는 방법이 있습니까?
편집 2 :
다음은이 작업을 수행하는 코드입니다. 바라건대 이것은 일부 Angular 2 개발자에게 답장을 장려하기에 충분히 공격적입니다. :-)
app.WordComponent = ng.core
.Component({
selector: 'word-editor',
template:'<input type="text" [value]="word.word" (input)="word.update($event.target.value)" (keydown)="keydown($event)"/>',
styles:[
''
],
properties:[
'list:list',
'word:word'
]
})
.Class({
constructor:[
function() {
}
],
keydown:function(e) {
if(e.which == 13) {
var ul = e.target.parentNode.parentNode.parentNode;
var childCount = ul.childNodes.length;
this.list.addWord("").then(function(word) {
var interval = setInterval(function() {
if(childCount < ul.childNodes.length) {
ul.lastChild.querySelector('input').focus();
clearInterval(interval);
}
}, 1);
});
}
}
});
그렇게 할 수 있다면 @Sasxa 답변에 참여하여 찾고있는 것과 더 비슷하게 수정합니다.
몇 가지 변경 사항
ngFor
angular2 를 사용하여 직접 수행하는 대신 새 입력을 추가합니다. 주된 목적은 angular2를 만들어 그것을 반복하는 것입니다.- 대신 속성 이있는 QueryList 를 반환하는
ViewChild
것을 사용할 것ViewChildren
입니다 . 이 속성은 Observable이며 변경된 요소를 반환합니다.changes
ES5에서는 데코레이터가 없기 때문에 queries
속성을 사용하여ViewChildren
구성 요소
Component({
selector: 'cmp',
template : `
<div>
// We use a variable so we can query the items with it
<input #input (keydown)="add($event)" *ngFor="#input of inputs">
</div>
`,
queries : {
vc : new ng.core.ViewChildren('input')
}
})
마지막 요소에 초점 을 맞 춥니 다 .
ngAfterViewInit: function() {
this.vc.changes.subscribe(elements => {
elements.last.nativeElement.focus();
});
}
앞서 말했듯이 ViewChildren은 changes
속성 이 포함 된 QueryList를 반환 합니다. 변경할 때마다 구독하면 요소 목록이 반환됩니다. 이 목록 elements
에는 last
마지막 요소를 반환 하는 속성이 포함되어 있습니다. 이 경우 마지막 요소를 사용 nativeElement
하고 마지막으로focus()
입력 요소 추가 이것은 순수한 편의를위한 것이며, 입력 배열은 ngFor
.
add: function(key) {
if(key.which == 13) {
// See plnkr for "this.inputs" usage
this.inputs.push(this.inputs.length+1);
}
}
배열에 더미 항목을 푸시하여 다시 그립니다.
ES5 사용 예 : http://plnkr.co/edit/DvtkfiTjmACVhn5tHGex
ES6 / TS 사용 예 : http://plnkr.co/edit/93TgbzfPCTxwvgQru2d0?p=preview
업데이트 29/03/2016
시간이 지났고 일이 명확 해졌으며 항상 배우고 가르 칠 모범 사례가 있습니다. 몇 가지를 변경하여이 답변을 단순화했습니다.
@ViewChildren
그것을 사용 하고 구독하는 대신 새로운 입력이 생성 될 때마다 설치 될 지침을 만들었습니다.Renderer
WebWorker를 안전하게 만들기 위해 사용 하고 있습니다. 원래 답변 은 권장되지 않는focus()
에 직접 액세스 합니다nativeElement
.- 이제
keydown.enter
키 다운 이벤트를 단순화하는 것을 듣고which
값 을 확인할 필요가 없습니다 .
요점. 구성 요소는 다음과 같습니다 (아래 plnkr의 단순화 된 전체 코드).
@Component({
template: `<input (keydown.enter)="add()" *ngFor="#input of inputs">`,
})
add() {
this.inputs.push(this.inputs.length+1);
}
그리고 지침
@Directive({
selector : 'input'
})
class MyInput {
constructor(public renderer: Renderer, public elementRef: ElementRef) {}
ngOnInit() {
this.renderer.invokeElementMethod(
this.elementRef.nativeElement, 'focus', []);
}
}
보시다시피 요소에 직접 액세스하는 대신 invokeElementMethod
트리거 focus
를 호출 하고 있습니다.
이 버전은 원래 버전보다 훨씬 깨끗하고 안전합니다.
plnkrs updated to beta 12
Example using ES5 : http://plnkr.co/edit/EpoJvff8KtwXRnXZJ4Rr
Example using ES6/TS : http://plnkr.co/edit/em18uMUxD84Z3CK53RRe
Update 2018
invokeElementMethod
is deprecated. Use Renderer2 instead of Renderer.
Give your element an id, and you can use selectRootElement:
this.renderer2.selectRootElement('#myInput').focus();
Take a look at ViewChild, here's a example. This might be what you're looking for:
import {Component, ViewChild} from 'angular2/core'
@Component({
selector: 'my-app',
providers: [],
template: `
<div>
<input #name>
</div>
`,
directives: []
})
export class App {
@ViewChild('name') vc: ElementRef;
ngAfterViewInit() {
this.vc.nativeElement.focus();
}
}
With inline angular code, focus after conditional paint:
<span *ngIf="editId==item.id">
<input #taskEditText type="text" [(ngModel)]="editTask" (keydown.enter)="save()" (keydown.esc)="saveCancel()"/>
<button (click)="save()">Save</button>
<button (click)="saveCancel()">Cancel</button>
{{taskEditText.focus()}}
</span>
You can implement a simple input text directive, so that whenever a new input is created, it will auto focus itself. The focus()
method is called inside of the ngAfterViewInit()
component lifecycle hook after the view is fully initialized.
@Directive({
selector: 'input[type=text]'
})
export class FocusInput implements AfterViewInit {
private firstTime: bool = true;
constructor(public elem: ElementRef) {
}
ngAfterViewInit() {
if (this.firstTime) {
this.elem.nativeElement.focus();
this.firstTime = false;
}
}
}
Use the FocusInput
directive in your component:
@Component({
selector: 'app',
directives: [FocusInput],
template: `<input type="text" (keyup.enter)="last ? addNewWord():0"
*ngFor="#word of words; #last = last" [value]="word.word"
#txt (input)="word.word = txt.value" />{{words |json}}`
})
export class AppComponent {
words: Word[] = [];
constructor() {
this.addNewWord();
}
addNewWord() {
this.words.push(new Word());
}
}
Note the following:
- The
(keyup.enter)
event is used to detect when the <enter> key is pressed ngFor
is used to repeat the input element for each word from the array ofwords
last
is a Boolean bound to a local variable which is true when the input is the last one- The keyup event is bound to the expression
last ? addNewWord() : 0
. This ensures that a new input field is only added when the <enter> key is pressed from the last Input
In order to prioritize which element will get focus when initializing several directives in same cycle, use:
Directive:
@Directive({
selector: '[focusOnInit]'
})
export class FocusOnInitDirective implements OnInit, AfterViewInit {
@Input('focusOnInit') priority: number = 0;
static instances: FocusOnInitDirective[] = [];
constructor(public renderer: Renderer, public elementRef: ElementRef) {
}
ngOnInit(): void {
FocusOnInitDirective.instances.push(this)
}
ngAfterViewInit(): void {
setTimeout(() => {
FocusOnInitDirective.instances.splice(FocusOnInitDirective.instances.indexOf(this), 1);
});
if (FocusOnInitDirective.instances.every((i) => this.priority >= i.priority)) {
this.renderer.invokeElementMethod(
this.elementRef.nativeElement, 'focus', []);
}
}
}
Usage:
<input type="text" focusOnInit="9">
https://plnkr.co/edit/T9VDPIWrVSZ6MpXCdlXF
참고URL : https://stackoverflow.com/questions/34522306/focus-on-newly-added-input-element
'program story' 카테고리의 다른 글
npm 오류! (0) | 2020.10.16 |
---|---|
Django : ORM이 알고있는 모델 목록을 어떻게 찾을 수 있습니까? (0) | 2020.10.16 |
열 3으로 awk 정렬을 사용하는 방법 (0) | 2020.10.16 |
다른 열 pandas 데이터 프레임을 기반으로 열 값 추출 (0) | 2020.10.16 |
사용자가 Django에서 자신의 비밀번호를 변경하도록 허용하는 방법은 무엇입니까? (0) | 2020.10.16 |