Search code examples
aurelia

Aurelia repeat.for within repeat.for


I will try and keep this as simple as possible.

We have a list of stations, each station has the ability to have up to 4 channels set.

Each station you can change any of the 4 stations. There is also a summary table below the form that shows what was chosen.

Any change made to the station level updates on the summary table below, but any update to the channel does not. I am wondering if this is something to do with the answer here https://stackoverflow.com/a/42629584/9431766

What I am confused about is if the station display updates, but the channels do not update.

Here is a simplified version of the code

constructor() {
  this.stations = [
    {
      name: 'Station 1',
      channels: [null, null, null, null]
    },
    {
      name: 'Station 2',
      channels: [null, null, null, null]
    },
    {
      name: 'Station 3',
      channels: [null, null, null, null]
    }
  ];

  this.channels = [
    { id: 1, name: 'Channel 1' },
    { id: 2, name: 'Channel 2' },
    { id: 3, name: 'Channel 3' },
    { id: 4, name: 'Channel 4' },
  ];

  this.activeStation = {}
}

editStation(station) {
  this.activeStation = station;
}
<div class="station">
  <input value.bind="activeStation.name"/>
  <div repeat.for="select of activeStation.channels">
    <select value.bind="activeStation.channel[$index]">
      <option model.bind="item" repeat.for="item of channels"></option>
    </select>
  </div>
</div>

<div class="summary">
  <div repeat.form="station of stations">
    <h3>${station.name}</h3>
    <div repeat.for="channel of station.channels">
      ${channel ? channel.name : 'N/A'}
    </div>
    <div class="edit"><a click.delegate="editStation(station)">Edit</a></div>
  </div>
</div>

If I reset the channels for each station after they have updated, only then does the summary update. I do this by using map to re-map the stations, ie; this.activeStation.channels = this.activeStation.channels.map(station);

I would prefer to not have to reset the channels after each update, this seems like a bit of overkill.


Solution

  • Nice question. The behavior you observed is because the repeat at the <div/> inside div.summary element couldn't see the changes to the array, since the mutation is done via index setter (caused by <select/> binding). So we have 2 choices:

    1. Make the mutation to channels array of each station notify the array observer
    2. Make the repeat aware of changes inside the array.

    For (2), we can do it either in your way, or a value converter way to avoid modifying source array on edit. You can see an example here https://codesandbox.io/s/httpsstackoverflowcomquestions59571360aurelia-repeat-for-within-repeat-for-yuwwv

    For (1), we need to resolve to manual change handling of the select, via change event

    EDIT: in v2, we already fixed this issue so it will properly & naturally work without us having to add these work around.