Is there any reason we should avoid passing a delegate into a component rather than a closure-action


#1

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.


Best solution for inter-component communication?