The Path to Contextual Components: Understanding dynamic components

The component helper allows the user to render a component based on a given name.

Given these two components:

{{! app/templates/components/first-component }}

This is first-component

{{name}}
{{! app/templates/components/second-component }}

This is second-component

{{name}}

We can render dynamically any of them with the following invocation:

{{component componentToRender name='Sergio'}}

The first parameter contains the name of the component you want to render. In this case, either 'first-component' or 'second-component'. The {{component}} helper passes everything but the first parameter to the component. In the example above, the rendered component receives name='Sergio'.

This twiddle demonstrates how to change the rendered component by changing a variable.

Rendering inputs and textareas

As of 2.3, inputs and textareas components cannot be rendered using dynamic components. The reason is simple: neither {{input}} nor {{texturea}} are components but helpers. There is a simple workaround for that. input is a helper around two components: Ember.TextField and Ember.Checkbox. Thus, we can extend those components just by creating new ones with no template and the following content:

// app/components/my-text-field
import Ember from 'ember';

// If you want to re-export it
export default Ember.TextField;

// If you want to extend it
export Ember.TextField.extend();
// app/components/my-checkbox
import Ember from 'ember';

// If you want to re-export it
export default Ember.Checkbox;

// If you want to extend it
export Ember.Checkbox.extend();

For textarea the code is pretty similar but with Ember.TextArea as the underlying component.

This twiddle demonstrates how it is done. There is a difference between using this technique and using a bound attribute to type. The former rises an assertion when using checkbox and a value attribute, like demonstrated in this twiddle.

Gotchas

  1. If null or undefined are passed as a component name, nothing is rendered.
  2. If a invalid or nonexistent component name is passed, an error is raised.

Go to the last post: Contextual Components!

Author: Serabe

Mathematician, and Ruby and JavaScript programmer. Sometimes I speak at conferences and local meetups.

Leave a Reply

Your email address will not be published. Required fields are marked *