I was reading a tutorial on emberigniter (which is an excellent site btw) which among other things shows how to pass an action-closure down into a component. The first set of code shown is from the emberignither example. The second set of code is similar but passes down a delegate that contains the actions. My main question is there any reason I should avoid using the delegate pattern, particularly if it’s a complex component (or hierarchy) that has a lot of actions?
// app/templates/components/todo-widget.hbs
{{add-todo onAdd=(action 'addTodo')}}
<ul>
{{#each todos as |todo|}}
<li>{{ todo.text }}</li>
{{/each}}
</ul>
// app/components/todo-widget.js
import Ember from 'ember';
export default Ember.Component.extend({
actions: {
addTodo(text) {
this.get('todos').pushObject({ text: text });
}
}
});
// app/components/add-todo.js
import Ember from 'ember';
export default Ember.Component.extend({
actions: {
submit() {
const text = this.get('text');
this.get('onAdd')(text);
this.set('text', "");
this.$('input').focus();
}
}
});
// add-todo.hbs
<form {{action "submit" on="submit"}}> {{input value=text}} <button type="submit">OK</button> </form>
This works great for a simple component with one or two actions, but I was wondering if there is any reason to avoid passing down a delegate object, that would basically implement an interface that the component can call. I think this is similar to what is done in iOS and android. So something like this:
{{add-todo delegate=addToDoDelegate}}
<ul>
{{#each todos as |todo|}}
<li>{{ todo.text }}</li>
{{/each}}
</ul>
// todo-widget.js
import Ember from 'ember';
export default Ember.Component.extend({
addToDoDelegate: Ember.computed(function(){
return this;
}),
addTodo(text) {
this.get('todos').pushObject({ text: text });
}
});
`// add-todo.js`
import Ember from 'ember';
export default Ember.Component.extend({
actions: {
submit() {
const addTodo = this.get('delegate').addTodo;
if (typeof addTodo === 'function') this.get('delegate').addTodo(text);
this.set('text', "");
this.$('input').focus();
}
}
});
In this case the parent component itself implements the interface (single method), but it could be any object.