WooDzu
WooDzu

Reputation: 4866

Inject controller actions from within Ember Addon

Lets say I have a standalone addon with a playback component:

{{my-record play="recordPlay" stop="recordStop"}}

/app/components/my-record.js

import Ember from 'ember';

export default Ember.Component.extend({
  actions: {
    play: function() {
      this.sendAction('play');
    },
    stop: function() {
      this.sendAction('stop');
    }
  }
});

I want the addon to work independently with backend and handle all actions internally. How do I handle these two actions recordPlay and recordStop from within the addon itself so that I don't need to touch controller/routes of the consuming application?

I have tried:

Can I use initializers somehow from within the addon to inject these two actions to ApplicationController?

EDIT: Dirty workaround using ApplicationRoute._actions

/app/initializers/record.js

export default {
  name: 'record',

  initialize: function(container, app) {

    var applicationRoute = container.lookup('route:application');

    applicationRoute._actions.recordPlay = function(id) {

        console.log('CALLED recordPlay', id);
    };

    applicationRoute._actions.recordStop = function(id) {

        console.log('CALLED recordStop', id);

    };
  }
};

Upvotes: 1

Views: 1007

Answers (1)

shaunc
shaunc

Reputation: 5611

It seems you are struggling to fulfill constraints that are almost contradictory -- this forces you into a solution that is probably worse than violating your constraints.

The constraints are: (1) component unaware of outside world, but (2) add-on as a whole interacts with the back-end autonomously.

Then your component signals it wants something done, and you want your add-on to provide a default way of doing things.

The idea of components unaware of the outside world is that then they can be used in different contexts. Is it realistic to use your component outside your addon? It seems like you want the "default way of doing things" to be baked in.

One way you could compromise is to use a blueprint to inject an adaptor into your component. The adaptor would then interact with the store (etc?). However, if a consumer wanted to do things differently, they could not define the adaptor and define actions instead, or use a different adaptor.

Upvotes: 0

Related Questions