adamesque
adamesque

Reputation: 1935

Invoking closure actions from a component's template

I'm instantiating a component and attaching some closure actions (new in Ember v1.13):

/app/templates/template.hbs

{{my-component key=val lookup=(action 'doLookup')}}

/app/templates/components/my-component.hbs

{{input value=coolField}}
<button {{action 'lookup' coolField}}>Look it up!</button>

/app/controllers/my-controller.js

export default Ember.Controller.extend({
  actions: {
    doLookup(field) {
      // do some work…
    }
  }
});

I was under the impression that I wouldn't need to define an action on the component in this case to wire things up. But so far it looks like this is required:

/app/components/my-component.js

export default Ember.Component.extend({
  actions: {
    lookup(field) {
      this.attrs.lookup(field);
    }
  }
});

Am I completely confused about how to use closure actions? It seems like wiring the action up in the component like this is just as much work as before (with regular actions).

Upvotes: 5

Views: 1051

Answers (2)

ronkot
ronkot

Reputation: 6347

I had exactly the same issue. Here's at least one way how closure actions can be used to avoid manually writing js code to forward actions.

/app/templates/template.hbs

{{my-component key=val lookup=(action 'doLookup')}}

/app/templates/components/my-component.hbs

{{input value=coolField}}
<button {{action (action 'lookup' coolField)}}>Look it up!</button>

/app/controllers/my-controller.js

export default Ember.Controller.extend({
  actions: {
    doLookup(field) {
      console.log('Looking up with cool field value', field);
    }
  }
});

Upvotes: 5

vikram-s-narayan
vikram-s-narayan

Reputation: 578

Tweaked your code for you (I tested and it works):

/app/templates/template.hbs => No change

/app/templates/components/my-component.hbs

{{input value=coolField}}
<button {{action 'lookup'}}>Look it up!</button>

/app/controllers/my-controller.js => No change

/app/components/my-component.js

export default Ember.Component.extend({
  actions: {
    lookup() {
      this.attrs.submit(this.get('coolField'));
    }
  }
});

Also, the stated reason for wiring up actions like this are (from the book Rock and Roll with Ember):

"Closure actions are clearly an improvement over old-style, bubbling actions. They are easier to reason about and debug because if the named action does not exist on the template's context, we'll get a clear error message ..."

"Another advantage of closure actions just being functions is that they have a return value that we can use at the point where we handle (call) the action. That may be leveraged to see if the upstream action was successful or to pass back additional information, something that was not possible with bubbling actions."

Upvotes: 0

Related Questions