@John_Davis wrote:
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:
//todo-widget.hbs
{{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.
Posts: 1
Participants: 1