RC3 {{input}} tags: potentially harmful

Ember.js RC3 introduced a new Handlebars helper, the {{input}} tag. From the release notes:

New Input and TextArea helpers

TextField, TextArea and Checkbox views now have corresponding handlebars helpers.

  {{view Ember.TextField valueBinding="name"}}
  {{view Ember.Checkbox  checkedBinding="isActive"}}
  {{view Ember.TextArea  valueBinding="name"}}

can now be expressed as:

  {{input value=name}}
  {{input checked=isActive}}
  {{textarea value=name}}

We recommend using the “dynamic tag” forms rather than the {{view}} forms because they are equivalent to the static tags that we all know and love.

Note that when using dynamic tags, you do not need to use a Binding suffix and must leave out the quotation marks around the values. Ember will interpret quoted strings as static strings in this context.

This seems very harmful to me. It breaks all of the current standards for creating a view in exchange for… being similar to HTML tags?

By abstracting away the creation of the views, it’s harder to figure out how they’re working. When a new developer decides he or she wants to create a custom view for their input, it’s not as obvious that they can extend Ember.TextField, Ember.Checkbox, or Ember.TextArea if they’re using helpers that abstract away their use. It’s also confusing that the Binding suffix isn’t used, unlike literally every other view tag a developer will use.

I don’t understand what problem this is solving. There are many issues with learning Ember, but I have never heard a developer say that the use of input views was confusing. Instead, it just serves to introduce problems.

1 Like

This must be a performance optimisation, clearly avoiding creating a view is always going to be faster than creating one.

Also, I guess one could argue that

{{bla}}

is “harmful” compared to

{{view SomeView valueBinding="bla"}}

Personally, I totally welcome changes that make Ember faster.

I will have to disagree with you. I have to say that I was already considering writing these helpers myself, because I felt, they were missing. I believe it is natural development. You already have a lot of helpers that in the past could only be solved by {{view}} but it was clunky. I am talking about {{partial}}, {{render}} and {{control}}. With these helpers you will probably not need {{view}} helper at all, or just in some special cases.

Ember is indeed faster in version RC3, but do not be mislead by these helpers. They are under the hood creating the view.

https://github.com/emberjs/ember.js/blob/v1.0.0-rc.3/packages/ember-handlebars/lib/controls.js#L34

2 Likes

I understand what you are saying, but I disagree. This change allows developers to be more concise and expressive in templates around a very common use case: forms.

As @myslik pointed out, there is precedent for these kinds of improvements in Ember. It is great to have {{outlet}}, {{render}} and our new form field helpers to simplify our templates.

All of Ember is built on nicely layered abstractions, and peeling off the onion layers is a fantastic way to learn and master the framework. But “killing boilerplate where it lives” is part of the mission statement of the framework and this change is totally aligned to that.

3 Likes

I believe that what makes it confusing for newcomers is the proximity of these terms with the regular DOM elements.

It is very different to get that {{outlet}} and {{render}} are Ember’s than {{input}} or {{textarea}}.

That being said, it will certainly speed up the code writing, which is always nice (power to Emblem!)

Abstractions are usually a good thing, I don’t disagree with that. But {{outlet}}, {{render}}, and {{control}} are very useful and have clear use cases.

{{input}}, on the other hand, is not so clear. Imagine a new Ember developer seeing {{input}} in an example. They’d immediately have several questions:

  • What is this tag doing?
  • What functionality does it have? How is it different from an <input> tag?
  • What options does it take? How can it be used?

{{view Ember.TextField valueBinding=myProperty}} is clear. It is creating a view called Ember.TextField, which is clearly predefined (as it’s on the Ember object), and must provide some functionality. Its value is bound to myProperty, so it must be doing some sort of two-way updating, as the Ember documentation clearly teaches a binding does. It also makes it obvious how to customize this view: simply extend Ember.TextField.

On the other hand, {{input value=myProperty}} is far more opaque. It’s easy to see that it’s creating an <input> tag and populating it with myProperty, but is it bound? Will it update the model? Is it an Ember view, or merely a shorthand to place myProperty within a text field? How would I customize it further - how do I add event listeners or change its behaviors?

Good APIs should be as self-documenting and consistent as possible. No matter how many layers of abstraction you are adding, you should easily be able to understand what is happening. {{input}} doesn’t do this. It’s not consistent with other views and hides what you’re actually doing.

(that’s not to say that there’s anything wrong with using boilerplate-hiding Handlebars helpers in your own code. I’m just bothered by the blog post saying that this is the preferred way to create these views.)

1 Like

I just kind of ran into the above post. I was happy that we have a shorter syntax and my first question was how do I use it for, say, blur event handling. Not sure I can do that though.

I don’t see how one abstraction more could be a problem for beginners, Ember is full of them!

I think this is a good abstraction to have and don’t really see any downsides.

It’s just a cleaner shortcut, it doesn’t prevent you from manually instantiating the relevant views yourself, it simplifies a common repetitive task in a way that makes perfect sense to me.

The only valid concern I see in this post is that new developers may not realize what’s happening under the hood, but for most cases they wont need to. I feel this concern can be adequately addressed with clear documentation of the shortcut nature of this helper that shows it’s equivalent.

As with any other helper that a new developer wants to learn more about, they will simply have to visit the docs.

  • What is this tag doing?
  • What functionality does it have? How is it different from an <input> tag?
  • What options does it take? How can it be used?

These questions are every bit as applicable to {{linkTo}} vs a tags, granted the helper name is different from the tag in that case, but I think curly braces vs angle brackets is more than enough to prevent confusion due to similar naming.

1 Like