首页 文章

Angular2自动对焦输入元素

提问于
浏览
33

如何自动对焦输入元素?与this问题类似,但与AngularDart不同 . 像这样的东西:

<input type="text" [(ngModel)]="title" [focus] />
//or 
<input type="text" [(ngModel)]="title" autofocus />

Angular2是否支持此功能?

最近的问题是this one,但是有没有更短/更容易的解决方案,因为我没有"list of input boxes" . 在提供的链接中使用 *ngFor="#input of inputs" ,但我在控件模板中只有1个输入 .

5 回答

  • 14
    <input type="text" [(ngModel)]="title" #myInput />
    {{ myInput.focus() }}
    

    只需在模板内输入后添加 {{ myInput.focus() }} 即可

  • 54

    这是我目前的代码:

    import { Directive, ElementRef, Input } from "@angular/core";
    
    @Directive({
        selector: "[autofocus]"
    })
    export class AutofocusDirective
    {
        private focus = true;
    
        constructor(private el: ElementRef)
        {
        }
    
        ngOnInit()
        {
            if (this.focus)
            {
                //Otherwise Angular throws error: Expression has changed after it was checked.
                window.setTimeout(() =>
                {
                    this.el.nativeElement.focus(); //For SSR (server side rendering) this is not safe. Use: https://github.com/angular/angular/issues/15008#issuecomment-285141070)
                });
            }
        }
    
        @Input() set autofocus(condition: boolean)
        {
            this.focus = condition !== false;
        }
    }
    

    用例:

    [autofocus] //will focus
    [autofocus]="true" //will focus
    [autofocus]="false" //will not focus
    

    Outdated code (old answer, just in case):
    我最终得到了这段代码:

    import {Directive, ElementRef, Renderer} from '@angular/core';
    
    @Directive({
        selector: '[autofocus]'
    })
    export class Autofocus
    {
        constructor(private el: ElementRef, private renderer: Renderer)
        {        
        }
    
        ngOnInit()
        {        
        }
    
        ngAfterViewInit()
        {
            this.renderer.invokeElementMethod(this.el.nativeElement, 'focus', []);
        }
    }
    

    如果我将代码放在 ngOnViewInit 中则不起作用 . 代码也使用最佳实践,因为直接调用元素不是recommended .

    Edited (conditional autofocus):
    几天前我需要条件自动对焦,因为我隐藏了第一个自动对焦元素,我想要聚焦另一个,但只有当第一个不可见时,我结束了这段代码:

    import { Directive, ElementRef, Renderer, Input } from '@angular/core';
    
    @Directive({
        selector: '[autofocus]'
    })
    export class AutofocusDirective
    {
        private _autofocus;
        constructor(private el: ElementRef, private renderer: Renderer)
        {
        }
    
        ngOnInit()
        {
        }
    
        ngAfterViewInit()
        {
            if (this._autofocus || typeof this._autofocus === "undefined")
                this.renderer.invokeElementMethod(this.el.nativeElement, 'focus', []);
        }
    
        @Input() set autofocus(condition: boolean)
        {
            this._autofocus = condition != false;
        }
    }
    

    Edited2:
    Renderer.invokeElementMethod is deprecated和新的Renderer2不支持它 . 所以我们回到原生焦点(例如在DOM-SSR之外不起作用!) .

    import { Directive, ElementRef, Input } from '@angular/core';
    
    @Directive({
        selector: '[autofocus]'
    })
    export class AutofocusDirective
    {
        private _autofocus;
        constructor(private el: ElementRef)
        {
        }
    
        ngOnInit()
        {
            if (this._autofocus || typeof this._autofocus === "undefined")
                this.el.nativeElement.focus();      //For SSR (server side rendering) this is not safe. Use: https://github.com/angular/angular/issues/15008#issuecomment-285141070)
        }
    
        @Input() set autofocus(condition: boolean)
        {
            this._autofocus = condition != false;
        }
    }
    

    用例:

    [autofocus] //will focus
    [autofocus]="true" //will focus
    [autofocus]="false" //will not focus
    
  • 32

    autofocus 是一个本机html功能,至少应该用于页面初始化 . 但是它无法与许多角度场景一起使用,尤其是 *ngIf .

    您可以制作一个非常简单的自定义指令来获得所需的行为 .

    import { Directive, OnInit, ElementRef } from '@angular/core';
    
    @Directive({
      selector: '[myAutofocus]'
    })
    export class AutofocusDirective implements OnInit {
    
      constructor(private elementRef: ElementRef) { };
    
      ngOnInit(): void {
        this.elementRef.nativeElement.focus();
      }
    
    }
    

    上述指令适用于我的用例 .

    如何使用

    <input *ngIf="someCondition" myAutofocus />
    

    编辑:似乎有一些用例,它可以在 OnInit 生命周期方法中尽早调用焦点 . 如果是这种情况,请改为 OnAfterViewInit .

  • 6

    以下指令适用于我使用Angular 4.0.1

    import {Directive, ElementRef, AfterViewInit} from '@angular/core';
    
    @Directive({
      selector: '[myAutofocus]'
    })
    export class MyAutofocusDirective implements AfterViewInit {
      constructor(private el: ElementRef)
      {
      }
      ngAfterViewInit()
      {
        this.el.nativeElement.focus();
      }
    }
    

    像这样用它:

    <md-input-container>
        <input mdInput placeholder="Item Id" formControlName="itemId" name="itemId" myAutofocus>
    </md-input-container>
    

    使用OnInit生命周期事件的选项对我不起作用 . 我也尝试在另一个对我不起作用的答案中使用渲染器 .

  • 11

    您可以为input元素分配模板引用变量 #myInput

    <input type="text" [(ngModel)]="title" #myInput />
    

    让你的组件实现 AfterViewInit ,使用 ViewChild 注释获取input元素的引用,并将你的元素集中在 ngAfterViewInit 钩子中:

    export class MyComponent implements AfterViewInit {
        @ViewChild("myInput") private _inputElement: ElementRef;
    
        [...]
    
        ngAfterViewInit(): void {
            this._inputElement.nativeElement.focus();
        }
    }
    

相关问题