Angular 关注<;输入>;要素

Angular 关注<;输入>;要素,angular,angular5,angular-forms,Angular,Angular5,Angular Forms,我正在使用Angular 5开发一个前端应用程序,我需要隐藏一个搜索框,但单击一个按钮,搜索框应该显示并聚焦 我尝试了一些使用指令或其他方法在StackOverflow上找到的方法,但没有成功 以下是示例代码: @Component({ selector: 'my-app', template: ` <div> <h2>Hello</h2> </div> <button (click) ="show

我正在使用Angular 5开发一个前端应用程序,我需要隐藏一个搜索框,但单击一个按钮,搜索框应该显示并聚焦

我尝试了一些使用指令或其他方法在StackOverflow上找到的方法,但没有成功

以下是示例代码:

@Component({
   selector: 'my-app',
   template: `
    <div>
    <h2>Hello</h2>
    </div>
    <button (click) ="showSearch()">Show Search</button>
    <p></p>
    <form>
      <div >
        <input *ngIf="show" #search type="text"  />            
      </div>
    </form>
    `,
  })
  export class App implements AfterViewInit {
  @ViewChild('search') searchElement: ElementRef;

  show: false;
  name:string;
  constructor() {    
  }

  showSearch(){
    this.show = !this.show;    
    this.searchElement.nativeElement.focus();
    alert("focus");
  }

  ngAfterViewInit() {
    this.firstNameElement.nativeElement.focus();
  }
@组件({
选择器:“我的应用程序”,
模板:`
你好
显示搜索

`, }) 导出类应用程序实现AfterViewInit{ @ViewChild(“搜索”)searchElement:ElementRef; 显示:假; 名称:字符串; 构造函数(){ } showSearch(){ this.show=!this.show; this.searchElement.nativeElement.focus(); 警惕(“关注”); } ngAfterViewInit(){ this.firstNameElement.nativeElement.focus(); }
搜索框未设置为焦点


我该怎么做呢?

像这样修改show搜索方法

showSearch(){
this.show=!this.show;
setTimeout(()=>{//这将在上述布尔值更改后执行
this.searchElement.nativeElement.focus();
},0);  
}

此指令将在显示元素时立即聚焦并选择元素中的任何文本。在某些情况下,这可能需要设置超时,但尚未进行过太多测试

从'@angular/core'导入{指令,ElementRef,OnInit};
@指示({
选择器:“[appPrefixFocusAndSelect]”,
})
导出类FocusOnShow指令实现OnInit{
构造函数(专用el:ElementRef){
如果(!el.nativeElement['focus']){
抛出新错误('元素不接受焦点');
}
}
ngOnInit():void{
常量输入:HTMLInputElement=this.el.nativeElement作为HTMLInputElement;
input.focus();
input.select();
}
}
在HTML中:


对此,您应该使用html自动对焦:

<input *ngIf="show" #search type="text" autofocus /> 


注意:如果您的组件被持久化并重新使用,它将仅在第一次附加片段时自动聚焦。这可以通过使用全局dom侦听器来克服,该侦听器在附加dom片段时检查dom片段内部的自动聚焦属性,然后通过javascript重新应用该属性或聚焦。

在布尔值更改后执行避免使用超时,您可以执行以下操作:

import { ChangeDetectorRef } from '@angular/core';

constructor(private cd: ChangeDetectorRef) {}

showSearch(){
  this.show = !this.show;  
  this.cd.detectChanges();
  this.searchElement.nativeElement.focus();
}

我将对此进行权衡(角度7解决方案)

input[appFocus]=“focus”。。。。
import{AfterViewInit,指令,ElementRef,Input,}来自'@angular/core';
@指示({
选择器:“输入[appFocus]”,
})
导出类FocusDirective实现AfterViewInit{
@输入('appFocus')
私有聚焦:布尔=假;
构造函数(公共元素:ElementRef){
}
ngAfterViewInit():void{
//ExpressionChangedTerithasBeenCheckedError:表达式在检查后已更改。
如果(这是重点){
setTimeout(()=>this.element.nativeElement.focus(),0);
}
}
}

这是在没有设置超时的情况下工作的i Angular 8:

import {AfterContentChecked, Directive, ElementRef} from '@angular/core';

@Directive({
  selector: 'input[inputAutoFocus]'
})
export class InputFocusDirective implements AfterContentChecked {
  constructor(private element: ElementRef<HTMLInputElement>) {}

  ngAfterContentChecked(): void {
    this.element.nativeElement.focus();
  }
}
从'@angular/core'导入{AfterContentChecked,Directive,ElementRef};
@指示({
选择器:“输入[inputAutoFocus]”
})
选中内容后导出类InputFocusDirective实现{
构造函数(私有元素:ElementRef){}
ngAfterContentChecked():void{
this.element.nativeElement.focus();
}
}
说明: 好的,这是因为:更改检测。这与setTimeout工作的原因相同,但在Angular中运行setTimeout时,它将绕过Zone.js并再次运行所有检查,它工作的原因是,当setTimeout完成时,所有更改都已完成。使用正确的生命周期挂钩(AfterContentChecked)同样的结果也可以实现,但其优点是不会运行额外的循环。当检查并传递所有更改时,该函数将启动,并在ContentInit和DoCheck之后的挂钩之后运行。如果我在这里出错,请纠正我

上的多个生命周期和更改检测

更新: 我发现了一种更好的方法,如果使用角材料CDK,a11y封装。 首先在模块中导入A11YMODEL,声明输入字段所在的组件。 然后使用cdkTrapFocus和cdkTrapFocusAutoCapture指令,在html中这样使用,并在输入上设置tabIndex:

<div class="dropdown" cdkTrapFocus cdkTrapFocusAutoCapture>
    <input type="text tabIndex="0">
</div>


更简单的方法也是这样做的

let elementReference = document.querySelector('<your css, #id selector>');
    if (elementReference instanceof HTMLElement) {
        elementReference.focus();
    }
let elementReference=document.querySelector(“”);
if(元素HtmleElement的引用实例){
elementReference.focus();
}

在Angular中,在HTML本身中,您可以通过单击按钮将焦点设置为输入

<button (click)="myInput.focus()">Click Me</button>

<input #myInput></input>
点击我

还有一个名为
cdkFocusInitial
的DOM属性,它对我的输入有效。
您可以在此处阅读更多信息:

仅使用角度模板

<input type="text" #searchText>

<span (click)="searchText.focus()">clear</span>

清楚的
组件的html:


组件控制器:

showSearch(){
this.show=!this.show;
}
..别忘了从

从'@angular/cdk/a11y'导入{A11yModule}

我有相同的场景,这对我来说很有效,但我没有你拥有的“隐藏/显示”功能。因此,也许你可以先检查当字段始终可见时是否获得焦点,然后尝试解决为什么在更改可见性时不起作用的问题(可能这就是你需要应用睡眠或承诺的原因)

要设置焦点,您只需进行以下更改:

您的Html mat输入应为:

<input #yourControlName matInput>
你的按钮很好,呼叫:

  showSearch(){
       ///blabla... then finally:
       this.yourControl.nativeElement.focus();
}
就这样。 您可以在我找到的这篇文章中查看此解决方案,感谢-->

这将只在每次页面刷新时工作一次,而不是多次。我在angular 7上尝试了这一方法,但不起作用,在angular 8中使用超时工作方式对我来说也不起作用,糟糕的是,我们必须返回到setTimeoutworking fine,设置而不是setTimeout,因为通过
setTimeout
影响页面的完全刷新。为什么我们需要使用setTimeout
  showSearch(){
       ///blabla... then finally:
       this.yourControl.nativeElement.focus();
}