1
votes

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:

  • creating application controller within the addon eg. `/app/controllers/application.js - this is never called

  • creating application route within the addon eg. `/app/routes/application.js - this is called unless consuming application has it's own ApplicationRoute which overrides the addon's route

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);

    };
  }
};
1
Why would you want to force the implementation on the index controller and not just handle it in the component? The index controller/route is only used when you're at the root of the application.Kingpin2k
Thanks for looking into this @Kingpin2k. To my knowledge component should not be aware of outside word - thus should not interact with store, ember data, APIs etc.. or am I missing some concept here?WooDzu
The idea behind injecting actions into ApplicationController is that a triggered action would bobble up the route tree from whatever is the current route. But still allows routes/resources to catch it mid-way through if neededWooDzu

1 Answers

0
votes

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.