One-way binding of mutable data through several layers of components


#1

Consider the following example. A top level component must maintain control over a model, as perhaps only it has the knowledge to initialize a new one, or it is responsible for maintaining it’s position or behavior within a list. This component then passes the model down through any number of other components, which may eventually want to make changes to the model or it’s properties:

// top-level.js
Component.extend({
  items: [a, b, c],

  actions: {
    itemChange (item, prop, value) {
      set(item, prop, value);
    }
  }
});
<!-- top-level.hbs -->
{{#each items as |item|}}
  {{item-component item onFormInput=(action "itemChange" item)}}
{{/each}}
// item-component.js
Component.extend({
  actions: {
    onFormInput () {
      this.onFormInput(...arguments);
    }
  }
});
<!-- item-component.hbs -->
...

{{item-form item onInput=(action "onFormInput")}}

...
// item-form.js
Component.extend({
  actions: {
    onInput () {
      this.onInput(...arguments);
    }
  }
});
<!-- item-form.hbs -->
{{input item.a update=(action "onInput" "a")}}

If I’m aiming to avoid two way binding the models and their properties, It looks like I’m stuck passing down “curried” actions which will eventually be used to update a property on the model. Is this an appropriate design for this scenario? Or am I unnecessarily complicating things?