【问题标题】:How to move focus on form elements the Angular way如何以 Angular 的方式将焦点移到表单元素上
【发布时间】:2016-12-25 23:35:11
【问题描述】:

目标

  • 我有一个包含一些输入元素(el1、el2 ...)的表单
  • el1 可能专注于开始与否
  • 当 keydown 事件触发时,执行以下操作:
    • 如果所有输入元素都没有焦点,则将焦点设置为第一个非空元素
    • 如果任何输入元素有焦点,检查是否按下了输入,是否移动到下一个任意元素
    • 在任何其他情况下,让钥匙按其意图行事

我当前的代码

form.component.html

<form>
      <input type="text" class="form-control" id="el1" name="el1"
             required focus
             [(ngModel)]="el1" #el1
             (keydown)="processEl1KeyDown($event)"
      >
      <input type="text" class="form-control" id="el2" name="el2"
             required
             [(ngModel)]="el2" #el2
             (keydown)="processEl2KeyDown($event)"
      >
</form>

form.component.ts

@Component({
    selector: 'my-form',
    templateUrl: 'app/form.component.html'
})
export class FormComponent {

    constructor(private renderer:Renderer) {
    }

    el1: string;
    el2: string

    @ViewChild("el1")
    el1El: ElementRef;

    @ViewChild("el2")
    el2El: ElementRef;


    @HostListener('document:keydown', ['$event'])
    handleKeyboardEvent(event: KeyboardEvent) {
        if (!this.el1) {
            this.setFocus(this.el1El);
        } else {
            this.setFocus(this.el2El);
        }
    }


    processEl1KeyDown(event: KeyboardEvent) {
        event.stopPropagation();
        if (event.keyCode == 13) {
            this.setFocus(this.el2El);
        }
    }


    processEl2KeyDown(event: KeyboardEvent) {
        event.stopPropagation();
        if (event.keyCode == 13) {
            this.submitForm();
        }
    }

    submitForm() {
        console.log("submit form");
    }

    setFocus(element: ElementRef) {
        this.renderer.invokeElementMethod(element.nativeElement, 'focus');
    }
}

问题

  1. 如何从 FormComponent 类中获取焦点元素(例如 #el1、#el2)的模板变量名称? document.activeElement 返回 DOM 元素。
  2. 我可以从 DOM 中获取 Angular2 对象吗?类似ElementRef.create('&lt;div&gt;&lt;/div&gt;')
  3. 如果我想将任意字符串传递给我的setFocus('el1') 函数,我该如何构建 ElementRef?我可以使用@ViewChild 装饰器,但我需要一些可以在运行时定义的东西?像新的ViewChild('el1')
  4. 还有什么比“Angular2”更能解决我的问题的方法?使用此答案中提到的 BehaviorSubject - Delegation: EventEmitter or Observable in Angular2?

编辑

也许问题不够清楚。总结一下:如果我有 n 个输入元素(el1,el2 ... eln),我如何知道模块中哪个元素具有焦点(可能通过模板变量),然后将焦点移动到不同的元素(通过字符串,再次对应另一个模板变量)。我想我正在查看 angular.element 等效项 - Get ComponentRef from DOM element,但我相信这可能不是正确的方法。

【问题讨论】:

  • @Günter:我知道这个问题,但是,我不知道它与我的问题有什么关系。也许我在做一些概念上错误的事情。我确实改写了我的问题,也许现在更清楚了。
  • 没有仔细看你的问题。只是认为链接到它可能会有所帮助。

标签: angular


【解决方案1】:

我认为焦点指令可能会解决您列出的大部分问题。我有类似的问题,并写了这个指令来解决它们:

@Directive
({
    selector: '[hasFocus]'
})

export class HasFocusDirective
{
    @Input("hasFocus") hasFocus: boolean;
    constructor(private elementRef: ElementRef) {}

    ngAfterViewInit()
    {
        if (this.hasFocus)
        {
            this.elementRef.nativeElement.focus();
        }
    }

    ngOnChanges(changes: SimpleChanges)
    {
        if (changes["hasFocus"] && changes["hasFocus"].currentValue === true)
        {
            this.elementRef.nativeElement.focus();
        }
    }
}

[hasFocus] 是一个布尔值,您可以使用任何布尔表达式来动态控制使用它的元素的焦点。

【讨论】:

  • @Directive 和 SimpleChanges 可能是正确的方向,但是我如何从组件中确定哪个元素被聚焦?你能给我举个例子吗?
猜你喜欢
  • 1970-01-01
  • 2012-01-05
  • 2016-06-30
  • 1970-01-01
  • 2014-10-25
  • 1970-01-01
  • 2015-12-30
  • 1970-01-01
  • 2016-12-27
相关资源
最近更新 更多