我正在构建本质上类似于Duolingo(SPA风格)的QuizTool / LMS。
tldr:依次单击plnkr,“ Check Answers”,“ Do Another”,然后注意第一个输入元素不再具有输入焦点-即使“ autofocus”属性似乎设置正确。我可以解决这个问题吗?
https://embed.plnkr.co/DU8opUuquP5MXlcfdHIe/
加长版:当我第一次进行测验时,我可以将输入焦点(使用绑定autofocus属性)设置到屏幕上的第一个输入区域(一个TEXTAREA,用户将在其中回答第一个问题)-这样用户可以刚开始打字。优秀。
但是,一旦用户提交了第一组问题(第一个测验),用户就可以选择“再做一次”测验-I / Angular能够重绘新的测验/ UI(到目前为止,发生了什么情况) (完全相同的问题),只有'autofocus'属性似乎不起作用-即第一个输入/文本区域没有获得焦点。
看来autofocus确实设置了bound 属性。
这意味着:1)我以某种方式错误地读取了属性2)它是Chrome中的错误(Mac OSX上的版本56.0.2924.87(64位))3)在此字段的自动对焦正确后,某些东西正在获取/窃取焦点设置4)等
我在ngFor循环中设置了“ firstQuestion”和“ lastQuestion”本地变量,以帮助证明已确定地设置了autofocus属性(只需将更[autofocus]="firstQuestion"改为[autofocus]="lastQuestion")。
我愿意解决此问题,但我需要这样做。整个“无控制器”的东西对我来说还是很新的,因此很可能我在整个设置中都做了一些愚蠢的事情。
我尝试使用Angular表单/ ngForm,但似乎没有什么不同。
我也很想知道我在哪里可以找到有关Angular2 Transitions /'controller'的基本教程,即如何重绘屏幕或切换到新视图等,而又没有发现什么呢? “传统”控制器。我认为使用VB时您会说:
oldForm.hide();
newForm.show();
如果这些都不起作用,我想手动设置焦点/ jqLite / HTML5之前的版本/无论如何-那里都还没有取得很大的成功-因此出现了这个问题。
谢谢。
不确定这有什么用处,但似乎我的应用程序(由ng cli工具设置)与plunkr产生的应用程序有很大不同。
我发现了:
组件加载完成后,外部/托管index.html页(如下所示)成为焦点。我添加了一个hack javascript函数,将焦点手动推回所需的元素,但这实际上只是用于测试。
<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>
Run Code Online (Sandbox Code Playgroud)更新:
固定。再次感谢@mickdev。
这是第一个解决方案的小转折。我将其描述为“在要呈现的组件上将模板引用变量与ngAfterViewChecked()生命周期方法一起使用”。
将此东西添加到要渲染的组件中:
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++
}
}
Run Code Online (Sandbox Code Playgroud)
然后添加模板引用变量“ #focusThis”:
<textarea #focusThis
[(ngModel)]="question.useranswer"
[disabled]="quiz.wasEvaluated"...
Run Code Online (Sandbox Code Playgroud)
这是一个(丑陋的)解决方法,但它有效:)首先,导入 ViewChild
import {Component, NgModule, ViewChild} from '@angular/core'
@ViewChild('test') test;
doAnother() {
this.quiz = new Quiz();
this.test.nativeElement.focus();
}
Run Code Online (Sandbox Code Playgroud)
然后更新视图:
<div><textarea [autofocus]="firstQuestion" #test></textarea></div>
Run Code Online (Sandbox Code Playgroud)
这是一个工作插件: 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>
Run Code Online (Sandbox Code Playgroud)
现在,您可以定位 DOM 中的任何文本区域。这是一个工作插件: https://plnkr.co/edit/izH61uVHBreEwdVQNoSf ?p=preview