Right now I am building a particular screen within my ember app that has an unknown number of nested components. Because of this I am trying not to change the url based on the component being shown also there is some base info I want to display on every sub screen.
Currently it seems like I have to redefine and pass in all these action names everywhere when the real action logic is only defined on the route. Is there a way to DRY these action references possibly in a controller or one "parent" component.
here is an example ember-twiddle where I am rendering these components into an outlet http://ember-twiddle.com/31a69c62ceddcb69b02b
here is an example of the route
import Ember from 'ember';
export default Ember.Route.extend({
_fixtureModels: [
{ person: {name: 'bill'}, sideModel: null},
{ person: {name: 'bill'}, sideModel: { postName: 'test post' }},
{ person: {name: 'bill'}, sideModel: { commentName: 'test comment'}}
],
_renderSideModel: function (template, sideModel) {
this.render();
this.render(template, {
outlet: 'side-model',
into: 'index',
model: sideModel
});
},
renderTemplate: function () {
this.render();
this.render('someComponentWrapper', {
outlet: 'side-model',
into: 'index'
});
},
model: function () {
return this._fixtureModels[0];
},
actions: {
renderTopLevel: function () {
return this.renderTemplate();
},
renderPost: function () {
return this._renderSideModel('post', this._fixtureModels[1]);
},
renderComment: function () {
return this._renderSideModel('comment', this._fixtureModels[2]);
}
}
});
I know URL is supposed to be king in Ember and this is pretty sinful but it would be very hard to reconstruct a potentially nested view.
So the reason you have to redefine all these action names is because components are designed to be isolated, i.e. reused anywhere. There are however, two shortcuts you can use:
You can use a default action name in your component to avoid having to specify it in every template.
// components/some-component.js
export default Ember.Component.extend({
renderPost: "renderPost",
renderComment: "renderComment"
});
// some template where you are using this component
{{some-component-wrapper renderPost="myRenderPost"}}
{{!overrides renderPost, but "inherits" an action named renderComment}}
See http://emberjs.com/blog/2015/06/12/ember-1-13-0-released.html#toc_closure-actions
This is a new feature that lets you pass a function down rather than a name of an action.