角2:关注新增加的input元素 [英] Angular 2: Focus on newly added input element

查看:229
本文介绍了角2:关注新增加的input元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个新的角度2应用程序与输入框列表。当用户点击回车键,我他们目前正在编辑所述一个之后立即增加一个新的输入框。或者说,我(异步地)一个新条目添加到模型中的阵列,这会导致角2自动生成,在不久的将来新的输入框。

我怎样才能让它会自动的输入焦点切换到新添加的元素?

另外,我到是造成要生成的DOM模型对象的引用。从组件code,有没有办法来搜索?

DOM元素重新presenting一个特定的模型对象

这里是我的code只是使这项工作。但愿这是足够的进攻有些角2开发者鼓励的答复: - )

  app.WordComponent = ng.core
    。零件({
        选择:文字编辑器,
        模板:'<输入类型=文本[值] =word.word(输入)=word.update($ event.target.value)(的keydown)=的keydown($事件)/&GT ;',
        款式:
            ''
        ]
        属性:[
            名单:名单,
            '字:单词
        ]
    })
    。类({
        构造函数:
            功能(){
            }
        ]
        KEYDOWN:功能(E){
            如果(e.which == 13){
                变种UL = e.target.parentNode.parentNode.parentNode;
                VAR childCount = ul.childNodes.length;                this.list.addWord()。然后(功能(字){
                    VAR间隔=的setInterval(函数(){
                        如果(childCount< ul.childNodes.length){
                            。ul.lastChild.querySelector(输入)专注();
                            clearInterval(间隔);
                        }
                    },1);
                });
            }
        }
    });


解决方案

如果我允许这样做,我会采取@Sasxa答案的一部分,并修改它,使它更喜欢你在找什么。

一些变化


  • 我将使用 ngFor 所以angular2增加了新的输入,而不是做自己。其主要目的是只是为了让angular2到迭代它。

  • /:
  • ViewChild 我要使用 ViewChildren 一个返回的 QueryList 其中有一个<一个href=\"https://github.com/angular/angular/blob/master/modules/angular2/src/core/linker/query_list.ts#L34\"相对=nofollow> 修改 财产。此属性是可观察到的,他们已经更改后返回的元素。

由于ES5我们没有任何装饰,我们必须使用查询属性使用 ViewChildren

组件

 组件({
    选择:CMP,
    模板:`
        &LT; D​​IV&GT;
            //我们使用一个变量,这样我们就可以查询它的项目
            &LT;输入#INPUT(的keydown)=增加($事件)* ngFor =输入#输入&GT;
        &LT; / DIV&GT;
    `
    查询:{
        VC:新ng.core.ViewChildren('输入')
    }
})

焦点的最后一个元素上

ngAfterViewInit:功能(){    this.vc.changes.subscribe(元素=&GT; {
        elements.last.nativeElement.focus();
    });}

就像我之前说的,ViewChildren返回一个包含QueryList 修改属性。当我们订阅它每次它变化,它会返回元素的列表。名单元素包含末页属性(等等),在这种情况下,返回的最后一个元素,我们使用 nativeElement 就可以了,最后焦点()

添加输入元素这是纯convenince,输入数组有没有什么实际意义超过重绘 ngFor

补充:功能(键){
    如果(key.which == 13){
        //为this.inputs用法见plnkr
        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 和订阅它,我提出,将instatiated一个指令每次创建一个新的输入

  • 我用渲染使其WebWorker安全。原来答案访问焦点()直接在 nativeElement 这是气馁。

  • 现在,我听 keydown.enter 简化了按键按下事件,我没有检查值。

要的地步。该组件看起来像(简体,全$下面的plnkrs C $ C)

@Component({
  模板:`&LT;输入(keydown.enter)=增加()* ngFor =#的输入输入&GT;`
})加(){
    this.inputs.push(this.inputs.length + 1);
}

和指示

@Directive({
  选择:输入
})
类MyInput {
  构造函数(公共渲染:渲染器,公共elementRef:ElementRef){}  ngOnInit(){
    this.renderer.invokeElementMethod(
      this.elementRef.nativeElement,'专注',[]);
  }
}

正如你可以看到我打电话 invokeElementMethod 引发焦点元素上直接访问它代替。

此版本比原来的更清洁,更安全。

plnkrs更新到公测12

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

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

I have a new Angular 2 app with a list of input boxes. When the user hits the return key, I add a new input box immediately after the one they're currently editing. Or rather, I (asynchronously) add a new entry to the array in the model, which causes Angular 2 to automatically generate a new input box in the near future.

How can I make it so that input focus changes to the newly added element automatically?

[edit] Alternatively, I get a reference to the model object that's causing the DOM to be generated. From the component code, is there a way to search for a DOM element representing a particular model object?

[edit] Here's my code to just make this work. Hopefully this is offensive enough to some Angular 2 devs to encourage a reply :-)

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

解决方案

If I'm allowed to do so, I will take part of @Sasxa answer and modify it to make it more like what you're looking for.

A few changes

  • I will use a ngFor so angular2 adds the new input instead of doing it myself. The main purpose is just to make angular2 to iterate over it.
  • Intead of ViewChild I'm going to use ViewChildren that returns a QueryList which has a changes property. This property is an Observable and it returns the elements after they've changed.

Since in ES5 we have no decorators we have to use the queries property to use ViewChildren

Component

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')
    }
})

Focus on the last element.

ngAfterViewInit: function() {

    this.vc.changes.subscribe(elements => {
        elements.last.nativeElement.focus();
    });

}

Like I said before, ViewChildren returns a QueryList which contains changes property. When we subscribe to it everytime it changes it will return the list of elements. The list elements contains a last property (among others) that in this case returns the last element, we use nativeElement on it and finally focus()

Add input elements This is for pure convenince, the inputs array has no real purpose more than redraw the ngFor.

add: function(key) {
    if(key.which == 13) {
        // See plnkr for "this.inputs" usage
        this.inputs.push(this.inputs.length+1);
    }
}

We push a dummy item on the array so it redraws.

Example using ES5 : http://plnkr.co/edit/DvtkfiTjmACVhn5tHGex

Example using ES6/TS : http://plnkr.co/edit/93TgbzfPCTxwvgQru2d0?p=preview

Update 29/03/2016

Time has passed, things have been clarified and there are always best practices to learn/teach. I've simplified this answer by changing a few things

  • Instead of using @ViewChildren and subscribing to it I made a Directive that will be instatiated everytime a new input is created
  • I'm using Renderer to make it WebWorker safe. The original answer accesses focus() directly on the nativeElement which is discouraged.
  • Now I listen to keydown.enter which simplifies the key down event, I don't have to check which value.

To the point. The component looks like (simplified, full code on the plnkrs below)

@Component({
  template: `<input (keydown.enter)="add()" *ngFor="#input of inputs">`,
})

add() {
    this.inputs.push(this.inputs.length+1);
}

And the directive

@Directive({
  selector : 'input'
})
class MyInput {
  constructor(public renderer: Renderer, public elementRef: ElementRef) {}

  ngOnInit() {
    this.renderer.invokeElementMethod(
      this.elementRef.nativeElement, 'focus', []);
  }
}

As you can see I'm calling invokeElementMethod to trigger focus on the element instead of accessing it directly.

This version is much cleaner and safer than the original one.

plnkrs updated to beta 12

Example using ES5 : http://plnkr.co/edit/EpoJvff8KtwXRnXZJ4Rr

Example using ES6/TS : http://plnkr.co/edit/em18uMUxD84Z3CK53RRe

这篇关于角2:关注新增加的input元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆