Angular2:自动对焦不适用于视图“刷新"(角度) [英] Angular2: Autofocus does not work on view 'refresh' (angular)

查看:57
本文介绍了Angular2:自动对焦不适用于视图“刷新"(角度)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建本质上类似于Duolingo(SPA风格)的QuizTool/LMS.

I'm building a QuizTool/LMS similar in nature to Duolingo (SPA-ish).

tldr:依次单击plnkr,"Check Answers","Do Another",然后注意第一个输入元素不再具有输入焦点-即使"autofocus"属性似乎是正确设置.我可以解决这个问题吗?

tldr: Hit the plnkr, 'Check Answers', 'Do Another', and notice the first input element no longer has the input focus -- even tho the 'autofocus' property seems to be set correctly. Can I fix this?

https://embed.plnkr.co/DU8opUuquP5MXlcfdHIe/

长版:当我第一次进行测验时,我可以将输入焦点(使用绑定的autofocus属性)设置到屏幕上的第一个输入区域(TEXTAREA,其中用户将回答第一个问题)-这样用户就可以开始打字了.很棒.

long version: When I first render a quiz, I am able to set the input focus (using a bound autofocus property) into the first input area on the screen (a TEXTAREA where the user will answer the first question) -- so the user can just start typing away. Excellent.

但是,一旦用户提交了第一组问题(第一个测验),用户就可以选择再做一次"测验-I/Angular能够重绘新的测验/UI(目前) ,碰巧是相同的问题),似乎只有'autofocus'属性似乎不起作用-即第一个输入/文本区域没有获得焦点.

However, once the user has submitted that first set of questions (the first quiz), the user can choose to 'Do Another' quiz -- I/Angular am able to redraw a new quiz/UI (with, for now, what happen to be the same exact questions), only the 'autofocus' attribute does not seem to work -- i.e. the first input/textarea does not get the focus.

但是,似乎确实设置了绑定的autofocus属性.

It does appear that the bound autofocus attribute is set, however.

这意味着: 1)我以某种方式错误地读取了属性 2)这是Chrome中的错误(Mac OSX上的版本56.0.2924.87(64位)) 3)在正确设置此字段的自动对焦后,某些东西正在获取/窃取焦点 4)等.

Which means either: 1) i'm reading the attribute incorrectly somehow 2) it's a bug in Chrome (Version 56.0.2924.87 (64-bit) on Mac OSX) 3) something is getting/stealing the focus after this field's autofocus is correctly set 4) etc.

我已经在ngFor循环中设置了"firstQuestion"和"lastQuestion"本地变量,以帮助证明已确定地设置了autofocus属性(只需将[autofocus]="firstQuestion"更改为[autofocus]="lastQuestion").

I've set up 'firstQuestion' and 'lastQuestion' local vars in the ngFor loop to help prove that the autofocus property is being set deterministically (just change the [autofocus]="firstQuestion" to [autofocus]="lastQuestion").

我愿意解决这个问题,但是我需要这样做.整个没有控制器"的事情对我来说还是很新的,所以很可能我在整个设置中都做得很愚蠢.

I'm open to fixing this however I need to. The whole 'no controller' thing is pretty new to me, so it's very possible I'm doing something stupid with this entire setup.

我尝试使用Angular表单/ngForm,但似乎没有什么作用.

I have tried using Angular forms/ngForm but it doesn't seem to make a difference.

我也很想知道我在哪里可以找到有关Angular2 Transitions/'controller'的基本教程,即如何重绘屏幕或切换到新视图等,而又没有什么可能被视为传统"控制器.我认为您在VB中说过类似的话:

I'd also be curious to know where I could find a basic tutorial on Angular2 transitions/'controller' stuff -- i.e. how do I redraw a screen, or switch to a new view, etc. -- without what might be considered a 'traditional' controller. I think with VB you said something like:

oldForm.hide(); newForm.show();

oldForm.hide(); newForm.show();

如果这些都不起作用,我想手动设置焦点/jqLit​​e/HTML5之前的版本/无论如何-那里都还没有取得很大的成功-因此出现了这个问题.

If none of this works, I want to set the focus manually/jqLite/pre-HTML5/whatever -- haven't had much success there yet either -- thus this question.

谢谢.

不确定它的用处如何,但看来我的应用程序(由ng cli工具设置)与plunkr所产生的内容有显着差异.

Not sure how useful this is, but it seems my app -- which was set up with the ng cli tool -- is different significantly than what plunkr is producing.

我能够发现:

  1. 即使将'document.activeElement'设置为正确的文本区域(根据查询DOM),对于用户开始输入文本,它仍然可能未被激活(我设置了红色bg使其非常直观)和
  2. 外部/托管index.html页面(如下所示)在组件加载完成后成为焦点.我添加了一个hack javascript函数,将焦点手动推回到所需的元素上,但这实际上只是用于测试.

  1. even if the 'document.activeElement' was set to the correct textarea (according to querying the DOM), it might still not be activate for the user to start inputting text (I set a red bg to make it very visual), and
  2. the outer/hosting index.html page, shown below, was getting the focus after my component finished loading. i added a hack javascript function to manually push the focus back to my desired element, but it was really just for testing.

<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>


更新:

已修复.再次感谢@mickdev.

Fixed. Thanks again to @mickdev.

这是第一个解决方案的小转折.我将其描述为在要呈现的组件上将模板引用变量与ngAfterViewChecked()生命周期方法一起使用".

This is a small twist on the first solution. I'd describe it as "using a template reference variable with the ngAfterViewChecked() lifecycle method on the component you are rendering".

将此内容添加到要渲染的组件中:

Add this stuff to the component you are rendering:

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++
    }
}

然后添加模板引用变量'#focusThis':

Then add the template reference variable, '#focusThis':

<textarea   #focusThis
            [(ngModel)]="question.useranswer" 
            [disabled]="quiz.wasEvaluated"...

推荐答案

这是一个(丑陋的)解决方法,但它可行:) 首先,导入ViewChild

Here is a (ugly) workaround but it works :) First, import 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>

这是一个正在工作的unk夫: https://plnkr.co/edit/S6wRn3tUTxZcOQdojzr6?p=preview

Here is a working 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中的任何文本区域作为目标.这是一个工作的小伙子: https://plnkr.co/edit/izH61uVHBreEwdVQNoSf?p=preview

Now, you can target any textarea in your DOM. Here is a working plunker : https://plnkr.co/edit/izH61uVHBreEwdVQNoSf?p=preview

这篇关于Angular2:自动对焦不适用于视图“刷新"(角度)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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