首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >关注新添加的输入元素

关注新添加的输入元素
EN

Stack Overflow用户
提问于 2015-12-30 10:56:39
回答 5查看 93.1K关注 0票数 80

我有一个新的Angular 2应用程序,带有一个input盒子列表。当用户按下return键时,我会在他们当前正在编辑的input框之后立即添加一个新框。或者,我(异步地)向模型中的数组添加一个新条目,这会导致Angular 2在不久的将来自动生成一个新的input框。

如何才能使input焦点自动切换到新添加的元素?

EDIT 1:

或者,我获得一个对导致生成DOM的模型对象的引用。从组件代码中,有没有办法搜索表示特定模型对象的DOM元素?

EDIT 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);
                });
            }
        }
    });
EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2016-01-03 12:04:34

如果我被允许这样做,我会将@Sasxa answer的一部分进行修改,使其更像您正在寻找的内容。

几个变化

  • 我将使用ngFor,因此angular2将添加新输入,而不是自己添加。主要目的是让angular2遍历它,

  • ,而不是ViewChild,我将使用ViewChildren,它返回一个QueryList,它有一个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 )。最初的答案是直接在discouraged.
  • Now上访问focus() I nativeElement to 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,而不是直接访问它。

这个版本比原来的版本更干净、更安全。

更新到测试版12 plnkr

使用ES5的示例:http://plnkr.co/edit/EpoJvff8KtwXRnXZJ4Rr

使用ES6/TS的示例:http://plnkr.co/edit/em18uMUxD84Z3CK53RRe

更新2018

invokeElementMethod已弃用。使用Renderer2而不是渲染器。

给你的元素一个id,你就可以使用selectRootElement

this.renderer2.selectRootElement('#myInput').focus();
票数 102
EN

Stack Overflow用户

发布于 2016-01-03 08:17:05

看看ViewChild,这是一个example。这可能就是你要找的:

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();
  }
}
票数 42
EN

Stack Overflow用户

发布于 2017-07-27 17:54:37

使用内联angular代码,在条件绘制后聚焦:

  <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>
票数 26
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34522306

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档