【问题标题】:Focus on input on each step of Angular wizard专注于 Angular 向导每一步的输入
【发布时间】:2020-07-07 21:46:10
【问题描述】:

环境

  • 角度 8
  • AZ-向导

要求

当用户移动到某个步骤时,我们需要让第一个(或特定的)元素获得焦点。每个步骤都有自己不同的元素(输入、按钮、下拉菜单等),这些元素应该会自动聚焦,因此用户无需手动单击即可开始流程。

代码尝试

  1. 在元素上使用autofocus 标签。除了第一个元素之外,这与向导一样不起作用,整套步骤都是一个 DOM。
  2. 在每个步骤的组件中使用 ngOnViewEdit 事件和 ViewChild 来设置焦点

    ngOnViewEdit() { var emailElement = (this.email.nativeElement); 如果(电子邮件元素){ emailElement.focus(); } 别的 alert("找不到邮件元素"); } 这也不起作用。还尝试使用 setTimeout 调用包装方法的主体,超时从 0 到 1000 不等。

  3. 在向导的stepEnter 中尝试访问 ViewChild 并尝试聚焦。这也失败了

组件界面

`<aw-wizard-step (stepEnter)="setFocus()">
    <app-cost-impact></app-cost-impact>
</aw-wizard-step>`

组件 TS

setFocus() { var emailComponent = <AddEmailComponent><unknown>this.wizard.currentStep; var emailElement = (<HTMLInputElement>emailComponent.email.nativeElement); if (emailElement) { emailElement.focus(); } else alert("Email element not found"); }

挑战

我们需要找出某种方法来访问每个步骤的元素,并使其足够通用以处理所有步骤

【问题讨论】:

    标签: html angular dom wizard


    【解决方案1】:

    这可以解决这个问题,只需将一个元素传递给setFocus 方法然后运行焦点方法。

      setFocus(elm:HTMLElement){
        setTimeout(() =>{
           elm.focus();
        })
      }
    

    模板

    <aw-wizard>
     <aw-wizard-step stepTitle="Title of step 1" (stepEnter)="setFocus(email)">
            Content of Step 1
            <button type="button" awNextStep>Next Step</button>
            <button type="button" awNextStep>Go directly to third Step</button>
            <input type="text" placeholder="email" #email>
     </aw-wizard-step>
     <aw-wizard-step stepTitle="Title of step 2" awOptionalStep (stepEnter)="setFocus(age)">
            Content of Step 2
            <button type="button" awPreviousStep>Go to previous step</button>
            <button type="button" awNextStep>Go to next step</button>
            <input type="text" placeholder="age" #age>
     </aw-wizard-step>
    </aw-wizard>
    

    demo ?

    【讨论】:

    • 每一步的内容都是一个专门的组件,那么元素是不是可以直接这样使用呢?
    • @malbarmavi,你不需要把“1”放在 setTimeout 函数中。一个 setTimeout 对 Angular 说:'嘿,等一下,你在完成所有其他功能并绘制应用程序后执行此指令“,所以正确的是 setTimeout(() =&gt;{elm.focus();})
    • @NitinSingh 你可以在每个组件中定义一个方法来设置焦点然后调用这个方法,查看演示第一步是这个的基础
    • 是否有可能定义一次通用的 setFocus 并且要通过组件传递要聚焦的元素。应用单一职责。否则演示工作正常
    • @NitinSingh 我只是在考虑将setFocus 逻辑作为基础移动到另一个类,然后从该类扩展所有步骤基础组件,您可以查看演示?
    【解决方案2】:

    尝试将输入元素的 id 传递给 setFocus 方法并更改 setFocus 方法如下:

      setFocus (id: string) {
            setTimeout(() => {
              var inputEl= document.getElementById(id);
              if (inputEl) {
                document.getElementById(inputEl).focus();
              }
            }, 0);
          }
    
    

    组件界面:

    
        `<aw-wizard-step (stepEnter)="setFocus('inputElementId')">
            <first-component></first-component>
        </aw-wizard-step>
        <aw-wizard-step (stepEnter)="setFocus('anotherElementId')">
            <second-component></second-component>
        </aw-wizard-step>
        `
    
    

    这样,您只需在相应的打字稿文件中声明一次 setFocus 方法,就可以通过传入输入元素的 id 将其用于任意数量的组件。

    【讨论】:

      猜你喜欢
      • 2018-09-30
      • 1970-01-01
      • 2018-09-19
      • 1970-01-01
      • 1970-01-01
      • 2012-05-19
      • 2016-10-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多