如何在控制器内的元素上触发焦点事件?

How to trigger focus event on element inside controller?

这是我的模板:

<div class="form-group">
  <label class="control-label" for="contact_email">Email address</label>
  {{
    input
    type="email"
    class="form-control"
    id="contact_email"
    placeholder="user@gmail.com"
    value=emailAddress
    autofocus="autofocus"
  }}
</div>
<button class="btn btn-primary btn-lg" disabled={{isSubmitButtonDisabled}} {{action 'saveEmail'}}>Submit</button>
{{#if responseMessage}}
   <div class="alert alert-success">{{responseMessage}}</div>
{{/if}}

这是控制器:

import Controller from '@ember/controller';
import { match, not } from '@ember/object/computed';

export default Controller.extend({
  emailAddress: '',
  responseMessage: '',
  isEmailValid: match('emailAddress', /^.+@.+\..+$/),
  isSubmitButtonDisabled: not('isEmailValid'),
  resetForm() {
    this.set('emailAddress', '');

    // focus email input field
  },
  actions: {
    saveEmail() {
      this.set(
        'responseMessage',
        'We got your email and we’ll get in touch soon'
      );

      this.resetForm();
    }
  }
});

是否有任何正确的方法来获取对控制器内电子邮件输入字段的引用,以便我可以集中注意力,而不仅仅是 document.querySelector()?

您可以定义应用于您要关注的输入的 ID,方法是将其传递给 ID 道具。
如果您在组件中,则可以将组件的 ID 连接到输入的名称。

在 componentjs 中构建 ID 并将其传递到输入字段的 ID 属性中。

refocusId: Ember.computed(function(){
    return `${this.get('elementId')}-someValue`; 
})
//HBS
id=refocusId

添加一项采取新 属性 并专注于此的行动。

refocus(){
  let element = document.getElementById(this.get('refocusId'));
  if (element) {
      element.focus();
  }
}

我有一个 working example in twiddle 你可以看看。

强烈 建议生成一个您在组件中使用的 ID。否则,您可能会不小心使用相同的 ID 两次。

编辑: 由于您在控制器中,因此您无法像在组件中那样访问 elementId。您实际上无权访问您可以使用的 public 属性 或方法。 所以,只要你在路由的控制器中这样做,你就可以在路由文件中使用 setupController 方法 + 路由名称。

setupController(controller, model) {
    let refocusId = `${this.get('routeName')}-someValue`;
    controller.set('refocusId', `${this.get('routeName')}-someValue`);
}

这可以在不对控制器进行任何其他更改的情况下完成。