ember-one-way-controls addon

Published on Feb 17, 2016

UPDATE: This is record speed for a video becoming outdated. Take note of Miguel Cambda's comment below. "The cursor position jump has been fixed in 2.3.1, so effectively, one-way-controls is not not necessary anymore, and discouraged in general because of being 40x slower. Unless, of course, you need to do something advanced that requires the input to be a component."

one-way-bound < input >s are great, but they have two problems: they’re verbose and (before Ember 2.3.1) there’s a bug when inserting characters in the middle of a field that’s changing oninput.

The ember-one-way-controls addon solves the bug and makes the syntax less verbose.

At the end, we discuss the tradeoffs of using this solution.


Links

Code

First, install the addon: ember install ember-one-way-controls.

Then make inputs like the following:

{{one-way-input value=monster.name update=(action (mut monster.name))}}

Transcript

One-way data binding with data going down and then an action going up is the way of the future with Ember. However, there are some problems still doing it like we have here. The first is that it’s long. It’s nearly three times as long as just doing a two-way bound input. The second is that it doesn’t take input well when in the middle. So I’m going to type something and notice what my cursor does. It automatically goes to the end once I typed one letter. Luckily, Ember-one-way-controls can help us with both of those problems.

So let’s go ahead and install the add-on with ember install ember-one-way-controls. And then we’ll restart our server. This add-on will give us a component called one-way-input. Let’s use that in our app.

So we replace this input with a one-way-input component, and then we’ll feed in our value, we don’t need to wrap it in mustaches anymore. And then we’ll replace oninput with update. And thankfully we can get rid of this value=''target.value''. Let’s see how this is working.

So it’s working exactly like it did before. So far this is a success. And let’s test here. This is awesome. We can type in the middle without it jumping to the end. So this has fixed both of our problems, both the jumping to the end problem and, well to a lesser extent, the verbosity problem. It’s only twice as long as the old way instead of three times as long. But there’s more.

So you can have key events, and the two that are included are onenter and onescape. Let’s try one of those. Here we’ll replace update with onenter, and when we do that... I’m going to have to narrate this for you. So here notice it’s not changing, but I’m going to hit Enter, and then it changes. So it doesn’t trigger on it updating, it triggers on me hitting the Enter key.

How it knows this is it’s the key up event. We’re defining '13' which is the key code for the Enter key as onenter. Now we can redefine some of these and define our own. Here, I’ve created my own version of this component. So first we import OneWayInput from 'ember-one-way-controls/components/one-way-input'.

Then we extend that, and here we’re just defining the default key events. These are the ones that are already in there. We’re not adding anything new. But we can add our own. So let’s say we add in '51' which is for the number 3. So we replace onenter with onthree, and let’s watch when this updates. The second I type 3, it updates. Now typing 3 is kind of a silly example, but it’s just an example of how you can expand the key events hash.

If you’re looking for more key events, then you can go to KeyboardEvent.keyCode in Mozilla developer’s documents and it’ll show you all the different codes. As you can see, 51, the number in the parenthesis is where we get what we put over here. And then over here is what we want to call it, onthree in this case.

So that's it for the documented features. But, what about recreating some of the things we saw last time, like onblur? While it' can't directly take the on events, like onblur, on input, but here is a list of some of the other events it can take. And in this case, thanks to Robert Jackson, I've been able to find the focusOut event. FocusOut is very similar to onblur, so we're going to set this to focusOut, and make a change, and click somewhere else... and, well, it did change, but it's giving it an entire object.

So when we were doing update, it was going directly through the one-way-input. But focusOut is something that you can put on any component, so it's not going through the one-way-input machinery, so its processed more like this. So we need to add in the value. So this is what it's going to be changed to. And here since it's an event we'll get the target, which is an element, and then we'll get the value of that element. So we'll see it working, and we'll click here and get the value from the one-way element.

So that’s ember-one-way-controls, an awesome add-on from some awesome people, and I hope you enjoy using it. I’ll see you next time.

Subscribe to our mailing list