How to handle app specific implementation in addon


#1

I just converted a form library I wrote into an addon so I could share it between projects. I also wrote my own language pak i18n translation tool that is semi coupled with the addon (eg label’s for the form are passed in as language pak keys). I want consumers of the addon to specify their own translation tool rather than couple it with mine.

Approaches: Make a function called translate on the form component, and and consumer of the addon has to reopen the form class and implement the translation function.

Have the form library use a translationService with a translate function and have the consuming app override this service via an initializer (I’m assuming this would work, haven’t tested).

Which really brings me to the crux of my question: how should addon configuration be handled? Using the app config didn’t seem like the easiest approach because I wasn’t sure how to import classes/functions I export default from the app (is there a syntax to require these functions from a file like environment.js). A configuration service object might be an alright approach as well, where the consuming app creates a custom initializer. Anyone with experience doing this, would love to hear from you!


#2

Hey,

You can use initializer and instance-initializer to setup and configure your addon service depending on app configs that user has provided in config/environment.js file.

Create addon/services/translation.js

import Ember from 'ember';

export default Ember.Service.extend({
  someProp: null
});

Setup app/config/environment.js in your app

ENV['translation'] = {
  someProp: null
};

Create addon/initializers/translation.js

import Translation from '../services/translation';

export function initialize(registry, application) {
  // here we register our service as 'translation:main' and inject into all routes/controllers
  registry.register("translation:main", Translation);
  application.inject('route', 'translation', 'translation:main');
  application.inject('controller', 'translation', 'translation:main');
}

export default {
  name: 'translation',
  initialize: initialize
};

Create addon/instance-initializers/translation.js

export function initialize(instance) {
  // look up user's app's config/environment.js file here
  let config = instance.container.lookupFactory('config:environment');
  // access the service
  let service = instance.container.lookup('translation:main');
  // set properties from app/config/environment.js on your service
  service.set('someProp', config.translation.someProp);
}

export default {
  name: 'translation',
  initialize: initialize
};

When the app finally boots up everything will be setted up.