简体   繁体   中英

What is the best “decoupled” way to give focus to an Aurelia component?

Let's say I've built some kind of Aurelia component. For this example, let's say I've built a hypothetical component called ui-money.

Let's say that the ui-money component comprises a text input element, and another element (eg. span) alongside the input that shows an exchange rate. In essence, something like:

<template>
   <input value.bind="amountStr" ... >
   <span>${exchange_rate}</span>
</template>

I then build an Aurelia view (page) which includes the <ui-money> element.

My question is this: let's say I want to put focus onto the "ui-money" element.

Practically speaking, I don't want to know the internal makeup of the ui-money element (white-box knowledge), nor should I want it. But clearly I need the focus to go to the INPUT element WITHIN the ui-money element.

So, it would seem that I need to ask the ui-money element to perform the act of setting focus, for me.

Now the most obvious first option would be to supply a ref to the ui-money element as such <ui-money ref="purchasePriceUx"> and have the ui-money view-model expose some kind of takeFocus() method. We could then invoke purchasePriceUx.takeFocus() .

But I'm interesting in knowing if there is a better way to achieve this, whilst still retaining the same level of decoupling.

You can use bindable properties and the focus attribute that ships with the standard configuration of the framework: https://gist.run/?id=7587f1453cb2632fa09b6fe542d9717c

The important stuff is here:

app.html

<template>
  <require from="./some-element"></require>

  <label for="hasFocus">Has Focus:</label> 
  <input id="hasFocus" type="checkbox" checked.bind="focus" />

  <div>
    Custom Element:
    <some-element has-focus.bind="focus" text.bind="text"></some-element>
  </div>
  <div>
    Regular text box: 
    <input type="text" value.bind="text" />
  </div>
</template>

some-element.html

<template>
  <input ref="textbox" type="text" value.bind="text" focus.bind="hasFocus" />
</template>

some-element.js

import {bindable, bindingMode} from 'aurelia-framework';

export class SomeElement {
  @bindable({ defaultBindingMode: bindingMode.twoWay }) text;

  // the bound property cannot be named focus as it interferes with
  // the focus custom attribute
  @bindable({ defaultBindingMode: bindingMode.twoWay })  hasFocus;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM