当前位置:  开发笔记 > 编程语言 > 正文

专注于新添加的输入元素

如何解决《专注于新添加的输入元素》经验,为你挑选了4个好方法。

我有一个新的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



1> Eric Martine..:

如果我被允许这样做,我将参加@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();



2> Sasxa..:

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



3> surfealokese..:

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

  
    
    
    
    {{taskEditText.focus()}}
  



4> pixelbits..:

您可以实现一个简单的输入文本指令,这样无论何时创建新输入,它都会自动对焦.在视图完全初始化之后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

推荐阅读
和谐啄木鸟
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有