关注新添加的输入元素

2024-05-24

我有一个新的 Angular 2 应用程序,其中包含以下列表input盒子。当用户按下返回键时,我添加一个新的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);
                });
            }
        }
    });

如果允许我这样做,我将参与@Sasxa 答案的一部分并对其进行修改,使其更像您正在寻找的内容。

一些变化

  • 我将使用一个ngFor所以 angular2 添加新的输入而不是我自己做。主要目的只是让 angular2 对其进行迭代。
  • 代替ViewChild我要使用ViewChildren返回一个查询列表 https://github.com/angular/angular/blob/master/modules/angular2/src/core/linker/query_list.ts其中有一个changes https://github.com/angular/angular/blob/master/modules/angular2/src/core/linker/query_list.ts#L34财产。该属性是一个 Observable,它会返回更改后的元素。

由于在 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')
    }
})

Focus在最后一个元素上。

ngAfterViewInit: function() {

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

}

正如我之前所说,ViewChildren 返回一个 QueryList,其中包含changes财产。当我们订阅它时,每次它发生变化时,它都会返回元素列表。列表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);
    }
}

我们推一个dummy数组上的项目,因此它会重绘。

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

使用 ES6/TS 的示例:http://plnkr.co/edit/93TgbzfPCTxwvgQru2d0?p=preview http://plnkr.co/edit/93TgbzfPCTxwvgQru2d0?p=preview

更新 29/03/2016

时间已经过去,事情已经澄清,并且总是有最佳实践可以学习/教授。我通过改变一些事情简化了这个答案

  • 而不是使用@ViewChildren并订阅它我制作了一个指令,每次创建新输入时都会实例化该指令
  • 我在用着Renderer确保 WebWorker 安全。原始答案访问focus()直接在nativeElement这是不鼓励的。
  • 现在我听keydown.enter这简化了按键事件,我不必检查which value.

说到点子上了。该组件看起来像(下面的 plnkrs 上的简化完整代码)

@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 更新至 beta 12

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

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

2018年更新

invokeElementMethod已弃用。使用 Renderer2 而不是 Renderer。

给你的元素一个id,你就可以使用选择根元素 https://angular.io/api/core/Renderer2#selectRootElement:

this.renderer2.selectRootElement('#myInput').focus();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

关注新添加的输入元素 的相关文章

随机推荐

  • next.js 13 服务器组件中的访问域和完整路径

    如何使用应用程序目录访问 Next js 13 中服务器组件中的域名和完整路径 在 Next js 的早期版本 例如版本 12 中 我可以使用 getServerSideProps 函数中的上下文来执行此操作 但应用程序目录中不再支持此操作
  • nodejs:process.stdout.write 的短别名

    我正在学习nodejs 而且我喜欢它 我试图弄清楚如何使用更短的别名console log我发现我可以使用var cout console log并使用cout string 从那时起 然后当我想使用process stdout write
  • Python Pandas 从宽到长的格式更改以及列标题拆分

    我有一个包含以下列标题和行示例的表 Subject Test1 Result1 Test1 Result2 Test2 Result1 Test2 Result2 0 John 10 0 5 20 0 3 我想将其改造成 Subject l
  • 为什么需要 JsonRequestBehavior?

    Why is Json Request Behavior needed 如果我想限制HttpGet对我的动作的请求我可以用 HttpPost 属性 Example HttpPost public JsonResult Foo return
  • 如何设置 AWS Appsync 请求超时限制 || AWSAppSync 客户端不提供回调

    我正在使用 AWS Appsync 来开发当前的应用程序 并面临一个严重的问题 即每当我在 Appsync 客户端中触发查询时 当互联网连接速度较慢时 请求永远不会以回调结束 我在互联网上查了一下 关于这个主题的信息来源有限 而且发现这个问
  • 我可以从 Socket.io 访问 cookie 吗?

    我想在 cookie 中设置一些用户信息并能够在连接时访问它 这可能吗 使用 Socket IO 0 8 7 您可以通过以下方式访问请求标头 套接字握手头文件 您可以在以下位置找到更多详细信息 https github com LearnB
  • 从本机代码访问 AsyncStorage

    我需要使用 JS 代码中的 AsyncStorage 将数据保存在本地存储中 我想知道是否有一种方法可以从本机代码 Objective C 或 Java 访问 AsyncStorage 存储的数据 Thanks 如果你导入RCTAsyncL
  • 如何在heroku上运行一个简单的文件

    假设我已经在 github 上安装了 Rails 应用程序 并且正在 heroku 上部署 github 存储库 我遇到过这样的情况 我有一个包含一堆单词的简单文本文件 它在我的 github 存储库中 我想将这些单词 使用简单的 ruby
  • 动态创建形状

    我有一个在 XML 中定义的形状对象 如下所示
  • getWidth() 和 getHeight 在 onMeasure() 之后返回零(特定设备)

    我注意到在调用 onMeasure 后 我的应用程序的视图为 getWidth 和 getHeight 返回 0 这种情况只发生在少数设备上 对于大多数 Android 设备 以下代码可以正常工作 我的 checkViewAndLoad 函
  • 如何使用ansible将vars文件包含在vars文件中?

    是否可以将 Ansible 中的 vars 文件动态包含到另一个 vars 文件中 IE 我有 vars 文件 definitions product web v2 suite mysuite include default step ym
  • 性能 多次插入或多值单次插入

    从性能角度 时间和服务器负载 来看 最好是进行多个插入或单个插入多个值 我在 stackoverflow 上发现每次插入最多可以有 1000 个值集 我说的是两种情况 要插入大约 1000 3000 个值 有时我会在 mySQL 数据库中插
  • 在 MongoDB Java 驱动程序中如何使用 $filter

    我有一个适用于 MQL 的查询 我需要将其翻译成Java MQL 中的查询如下所示 db
  • ssas维度处理键未找到错误

    我有一个奇怪的情况 我正在尝试处理维度 数据源是 MSSQL 当我尝试处理这个维度时 我收到此错误 OLAP存储引擎中的错误 处理时找不到属性键 表 application 列 Full Name 值 Mr Peter McDonald 该
  • 使用 C++ REST SDK Casablanca 发送 HTTP POST 请求以更新文件内容

    我正在尝试使用 C Rest sdk 更新 alfresco 服务器中的文件内容 我正在使用 alfresco CMIS url 发送请求 更具体地说 它是 Alfresco CMIS 浏览器绑定 我必须坚持浏览器绑定而不是原子绑定 当我发
  • 还记得我的 Cookie 最佳实践吗?

    我读到了许多关于这个论点的老问题 我认为最好的做法是设置一个 cookieusername user id和一个随机令牌 相同 cookie 的数据在 cookie 创建时存储在数据库中 当用户拥有 cookie 时 它 们会进行比较 co
  • 为什么 git 默认执行快进合并?

    来自 Mercurial 我使用分支来组织功能 当然 我也希望在我的历史中看到这个工作流程 我使用 git 开始了我的新项目并完成了我的第一个功能 当合并该功能时 我意识到 git 使用快进 即如果可能的话 它会将我的更改直接应用到主分支
  • hive 添加分区语句忽略前导零

    我在 hdfs 上有文件夹 user test year 2016 month 04 dt 25 000000 0 需要将上面的分区路径添加到test table 命令 ALTER TABLE test ADD IF NOT EXISTS
  • 如何在 ASP.NET Core Razor Pages 中为单页应用程序创建包罗万象的路由?

    对于单页应用程序 我们希望能够将所有未处理的请求路由到索引 以便处理路由客户端 以前 我们将使用 MapRoute 添加路线 详细信息请参见这个答案 https stackoverflow com questions 42414397 as
  • 关注新添加的输入元素

    我有一个新的 Angular 2 应用程序 其中包含以下列表input盒子 当用户按下返回键时 我添加一个新的input紧接着他们当前正在编辑的框后面的框 或者更确切地说 我 异步 向模型中的数组添加一个新条目 这会导致 Angular 2