Search code examples
bindingaureliacustom-element

Aurelia binding an object in a custom element


I have an object 'visit' that has several properties (e.g. visit1 = {id: 1, clientId: "0001", startTime: 1234567890, finishTime: 1234567899}). The visits are stored in the array 'shifts' that looks like shifts = [{id:1, visits: [visit1, ...]}, ...].

To display the data in the view, I use repeat.for:

<div repeat.for="shift of shifts">
  <ul>
    <li repeat.for="visit of shift.visits">
      <visit-item visit.bind="visit" settings.bind="userSettings" selectors="selectors"></visit-item>
    </li>
</ul>
</div>

'visit-item' is a custom element displaying the editable form for a single visit. Its view is:

<template>
<require from="./timepicker"></require>
<require from="../../converters/hour-format"></require>
<form class="form-horizontal" role="form">
    <div class="col-xs-12 col-md-3 col-lg-3">
        <label>start</label><input timepicker class="form-control input-sm" id="startTime_${visit.id}" type="text" value.bind="visit.startTime | hourFormat">
      </div>
      <div class="col-xs-12 col-md-3 col-lg-3">
        <label>finish</label><input timepicker class="form-control input-sm" id="finishTime_${visit.id}" type="text" value.bind="visit.finishTime | hourFormat">
      </div>
      <div class="col-xs-12 col-md-3 col-lg-3">
        <label>client</label><select class="form-control input-sm" id="client_${visit.id}" value.bind="visit.clientId">
          <option repeat.for="option of selectors.client" model.bind="option.value" disabled.bind="option.disabled">${option.name}</option>
        </select>
      </div>
    </form>
</template>

The view-model of visit-item:

import {bindable, bindingMode} from 'aurelia-framework';
export class VisitItemCustomElement {
  @bindable({ defaultBindingMode: bindingMode.twoWay }) visit;
  @bindable selectors;
  constructor()  {
  }
  bind()  {
  }
  visitChanged(newValue, oldValue)  {
    console.log("visit changed");
  }
}

I try to catch changes in the form of a visit by visitChanged() method, but visit-item's view-model doesn't call this method when I change values in the form. The same if I do valueChanged(). Is there any way to catch changes in the form with the described data design?


Solution

  • The problem is that the visit isn't changing, it's the properties on visit that are changing. Since you only have a small number of properties you are binding to, you'd be best served by creating a bindable property on visit-item for each property you need to to be notified of changes.