我有一个新的Angular 2应用程序,其中包含一个输入框列表.当用户点击返回键时,我会在他们当前正在编辑的输入框之后立即添加一个新输入框.或者更确切地说,我(异步)在模型中向数组添加一个新条目,这使得Angular 2在不久的将来自动生成一个新的输入框.
如何使输入焦点自动更改为新添加的元素?
[edit]或者,我得到了一个引起DOM生成的模型对象的引用.从组件代码中,有没有办法搜索表示特定模型对象的DOM元素?
[编辑]这是我的代码,使这项工作.希望这对一些Angular 2开发者来说足够冒犯以鼓励回复:-)
app.WordComponent = ng.core .Component({ selector: 'word-editor', template:'', 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); }); } } });
Eric Martine.. 99
如果我被允许这样做,我将参加@Sasxa的答案并修改它,使其更像你正在寻找的.
一些变化
我将使用一个ngFor
如此angular2添加新的输入而不是自己做.主要目的是让angular2迭代它.
而不是ViewChild
我要使用ViewChildren
它返回一个具有属性的QueryListchanges
.此属性是一个Observable,它在更改后返回元素.
因为在ES5中,我们没有装饰器,所以我们必须使用该queries
属性ViewChildren
零件
Component({ selector: 'cmp', template : `// We use a variable so we can query the items with it`, 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
2016年3月29日更新时间已经过去,事情已经澄清,并且总是有最好的实践来学习/教学.我通过改变一些事情简化了这个答案
@ViewChildren
我创建了一个指令,而不是使用和订阅它,每次创建新输入时都会实例化
我正在使用Renderer
它使WebWorker安全.原始答案focus()
直接访问nativeElement
不鼓励的.
现在我听听keydown.enter
哪个简化了按键事件,我没有检查which
值.
到了这一点.组件看起来像(下面的plnkrs上的简化,完整代码)
@Component({
template: ``,
})
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更新为beta 12
使用ES5的示例:http://plnkr.co/edit/EpoJvff8KtwXRnXZJ4Rr
使用ES6/TS的示例:http://plnkr.co/edit/em18uMUxD84Z3CK53RRe
更新2018年invokeElementMethod
已弃用.使用Renderer2而不是Renderer.
为您的元素指定一个id,您可以使用selectRootElement:
this.renderer2.selectRootElement('#myInput').focus();
Sasxa.. 40
看看ViewChild,这是一个例子.这可能是你正在寻找的:
import {Component, ViewChild} from 'angular2/core' @Component({ selector: 'my-app', providers: [], template: ``, directives: [] }) export class App { @ViewChild('name') vc: ElementRef; ngAfterViewInit() { this.vc.nativeElement.focus(); } }
surfealokese.. 24
使用内联角度代码,在条件绘制后聚焦:
{{taskEditText.focus()}}
pixelbits.. 9
您可以实现一个简单的输入文本指令,这样无论何时创建新输入,它都会自动对焦.在视图完全初始化之后focus()
,在ngAfterViewInit()
组件生命周期钩子内部调用该方法.
@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; } } }
FocusInput
在组件中使用该指令:
@Component({ selector: 'app', directives: [FocusInput], template: `{{words |json}}` }) export class AppComponent { words: Word[] = []; constructor() { this.addNewWord(); } addNewWord() { this.words.push(new Word()); } }
请注意以下事项:
该(keyup.enter)
事件用于检测何时按下
ngFor
用于重复数组中每个单词的输入元素 words
last
是绑定到局部变量的布尔值,当输入是最后一个时,该变量为true
keyup事件绑定到表达式last ? addNewWord() : 0
.这可确保仅在从最后一个输入按下
演示Plnkr
如果我被允许这样做,我将参加@Sasxa的答案并修改它,使其更像你正在寻找的.
一些变化
我将使用一个ngFor
如此angular2添加新的输入而不是自己做.主要目的是让angular2迭代它.
而不是ViewChild
我要使用ViewChildren
它返回一个具有属性的QueryListchanges
.此属性是一个Observable,它在更改后返回元素.
因为在ES5中,我们没有装饰器,所以我们必须使用该queries
属性ViewChildren
零件
Component({ selector: 'cmp', template : `// We use a variable so we can query the items with it`, 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
2016年3月29日更新时间已经过去,事情已经澄清,并且总是有最好的实践来学习/教学.我通过改变一些事情简化了这个答案
@ViewChildren
我创建了一个指令,而不是使用和订阅它,每次创建新输入时都会实例化
我正在使用Renderer
它使WebWorker安全.原始答案focus()
直接访问nativeElement
不鼓励的.
现在我听听keydown.enter
哪个简化了按键事件,我没有检查which
值.
到了这一点.组件看起来像(下面的plnkrs上的简化,完整代码)
@Component({
template: ``,
})
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更新为beta 12
使用ES5的示例:http://plnkr.co/edit/EpoJvff8KtwXRnXZJ4Rr
使用ES6/TS的示例:http://plnkr.co/edit/em18uMUxD84Z3CK53RRe
更新2018年invokeElementMethod
已弃用.使用Renderer2而不是Renderer.
为您的元素指定一个id,您可以使用selectRootElement:
this.renderer2.selectRootElement('#myInput').focus();
看看ViewChild,这是一个例子.这可能是你正在寻找的:
import {Component, ViewChild} from 'angular2/core' @Component({ selector: 'my-app', providers: [], template: ``, directives: [] }) export class App { @ViewChild('name') vc: ElementRef; ngAfterViewInit() { this.vc.nativeElement.focus(); } }
使用内联角度代码,在条件绘制后聚焦:
{{taskEditText.focus()}}
您可以实现一个简单的输入文本指令,这样无论何时创建新输入,它都会自动对焦.在视图完全初始化之后focus()
,在ngAfterViewInit()
组件生命周期钩子内部调用该方法.
@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; } } }
FocusInput
在组件中使用该指令:
@Component({ selector: 'app', directives: [FocusInput], template: `{{words |json}}` }) export class AppComponent { words: Word[] = []; constructor() { this.addNewWord(); } addNewWord() { this.words.push(new Word()); } }
请注意以下事项:
该(keyup.enter)
事件用于检测何时按下
ngFor
用于重复数组中每个单词的输入元素 words
last
是绑定到局部变量的布尔值,当输入是最后一个时,该变量为true
keyup事件绑定到表达式last ? addNewWord() : 0
.这可确保仅在从最后一个输入按下
演示Plnkr