quinta-feira, 19 de março de 2015

How to modify an ember component from a controller.

The Problem

How do I change state in an ember component from an ember controller? For instance, calling a method or setting a variable?

The solution

The simple way is to share a property between the controller and the component. That is the gist of two-way binding, after all! What we may do is to use the binding facilities in Ember.

At the controller:

App.MyRouteController = Ember.Controller.extend({
    myComponent1Var: false;
    myComponent2Var: false;

    (...)
});

We have defined two property for two different instances of MyOwnComponent. At the component we will now pass the property at the controller as a binding for a component property

At the route template:

{{my-own-component varBinding="controller.myComponent1Var}}

(...)

{{my-own-component varBinding="controller.myComponent2Var}}

At this point, two instances of MyOwnComponent share completely different variables. Now, each of the components shares it's own property with the controller, and the property is called var (from varBinding). The component knows nothing about the controller and the controller knows nothing about the component. They just share state.

But what if I want to call a method at the component from the controller? Just watch the common property at the component. Add this to the component:

App.MyOwnComponent = Ember.Component.extend({
    (...)

    varChanged: function() {
        if (this.get('var')) {
            this.method();
        }
    }.observes('var');

    (...)
});

At the varChanged method, the method named method is called whenever the property var changes into a truish value.

The two-way binding allows one to communicate from a controller to a component ª(and vice-versa) without any of these objects having to ke aware of the other.