我正在构建一个类似于Duolingo(SPA-ish)的QuizTool / LMS。
tldr:点击plnkr,'检查答案','做另一个',并注意第一个输入元素不再具有输入焦点 - 即使'自动对焦'属性似乎是设置正确。我能解决这个问题吗?
https://embed.plnkr.co/DU8opUuquP5MXlcfdHIe/
长版本:当我第一次渲染测验时,我能够将输入焦点(使用绑定的autofocus
属性)设置到屏幕的第一个输入区域(TEXTAREA用户将回答第一个问题) - 因此用户可以开始输入。优异。
然而,一旦用户提交了第一组问题(第一个测验),用户就可以选择“做另一个”测验 - 我/ Angular能够重新绘制新的测验/用户界面(现在, ,恰好是相同的问题),只有'自动对焦'属性似乎不起作用 - 即第一个输入/ textarea没有得到焦点。
但是,似乎设置了绑定的autofocus
属性。
这意味着: 1)我正在以某种方式错误地读取属性 2)这是Chrome中的一个错误(Mac OSX上的版本56.0.2924.87(64位)) 3)正确设置此字段的自动对焦后,某些东西正在/正在窃取焦点 4)等。
我在ngFor
循环中设置了'firstQuestion'和'lastQuestion'本地变量,以帮助证明自动对焦属性是确定性设置的(只需将[autofocus]="firstQuestion"
更改为{{1} })。
我愿意解决这个问题,但我需要这样做。整个'无控制器'的东西对我来说都是新鲜的,所以我很可能在整个设置中做一些愚蠢的事情。
我尝试过使用Angular forms / ngForm,但它似乎没什么区别。
我也很想知道在哪里可以找到关于Angular2过渡/'控制器'的基本教程 - 即如何重绘屏幕,或切换到新视图等等 - 没有什么可能被视为“传统”控制者。我认为用VB你会说:
[autofocus]="lastQuestion"
如果这一切都不起作用,我想手动设置焦点/ jqLite / pre-HTML5 /无论如何还没有取得多少成功 - 因此这个问题。
谢谢。
不确定这是多么有用,但似乎我的应用程序 - 使用ng cli工具设置 - 与plunkr正在生成的有很大不同。
我能够发现:
外部/托管index.html页面(如下所示)在我的组件加载完成后获得了焦点。我添加了一个hack javascript函数来手动将焦点推回到我想要的元素,但它实际上只是用于测试。
oldForm.hide();
newForm.show();
更新
固定。再次感谢@mickdev。
这是第一个解决方案的一个小转折。我将其描述为“在正在渲染的组件上使用带有ngAfterViewChecked()生命周期方法的模板引用变量”。
将此内容添加到您要呈现的组件中:
<script>
setInterval(function(){
if(document.activeElement!=null){
if(document.activeElement.id!='textarea-0'){ // find first input element on the page
document.getElementById('textarea-0').focus(); // set the focus
}
}
},
5000);
</script>
然后添加模板引用变量'#focusThis':
import { ViewChild } from '@angular/core';
@ViewChild('focusThis') focusThis;
// to keep track of which element in our loop we are in
id:number=0
//wait for viewchild to update then focus
ngAfterViewChecked(){
// only focus the 0th (i.e. first) element of our loop
if(this.id == 0){
this.focusThis.nativeElement.focus();
this.id++
}
}
答案 0 :(得分:2)
这是一个(丑陋的)解决方法,但它有效:) 首先,导入ViewChild
import {Component, NgModule, ViewChild} from '@angular/core'
@ViewChild('test') test;
doAnother() {
this.quiz = new Quiz();
this.test.nativeElement.focus();
}
然后更新视图:
<div><textarea [autofocus]="firstQuestion" #test></textarea></div>
这是一个工作的plunker: https://plnkr.co/edit/S6wRn3tUTxZcOQdojzr6?p=preview
更新:这是一种更优雅的方式来实现此目标ElementRef
//component
import {Component, NgModule, ElementRef} from '@angular/core'
this.element.nativeElement.querySelector('#textarea-1').focus()
//template
<div><textarea id="textarea-{{ question.id }}" [autofocus]="firstQuestion"></textarea></div>
现在,您可以定位DOM中的任何textarea。这是一个工作的plunker: https://plnkr.co/edit/izH61uVHBreEwdVQNoSf?p=preview
答案 1 :(得分:1)
<input type="text" #myInput />
{{ myInput.focus() }}
在模板
中输入后立即添加{{myInput.focus()}}