简体   繁体   中英

Aurelia CollectionObserver handler is not triggered when collection is changed

I have an Aurelia component that is just supposed to display a list of items. The component's model has an "items" property which is bindable:

@bindable items = [];

The component template displays the list using a simple repeat attribute:

 <div repeat.for="item of items">  
    ${item.id}   </div>

When I push a new item in my bound array from the page's viewmodel where the component is used, I can see the item being added as the list is refreshed and the new item appears. My problem is that I need to perform other actions when the 'items' array is modified so I tried to add a collectionObserver to the component like this:

import {BindingEngine, inject} from 'aurelia-framework';

@inject(BindingEngine) 
export class GridControl {   

  @bindable items = [];

  constructor(bindingEngine) {
    this.items = []; 
    let subscription = bindingEngine.collectionObserver(this.items)
                                    .subscribe(this.listChanged);   
  }

  listChanged(splices) {
    // do some stuff   
  } 
}

But my 'listChanged' handler never gets called. Any idea why?

In the constructor, bindingEngine.collectionObserver(this.items) is called.

Later, when the component is data-bound, this.items is assigned a different array instance via the data-binding. This different array instance is not the one you passed to the binding engine for observation.

Try doing something like this:

import {BindingEngine, inject} from 'aurelia-framework';

@inject(BindingEngine) 
export class GridControl {   
  @bindable items;

  constructor(bindingEngine) {
    this.bindingEngine = bindingEngine;
  }

  listChanged(splices) {
    // do some stuff   
  }

  subscribeItems() {
    if (this.items) {
      this.subscription = this.bindingEngine.collectionObserver(this.items)
        .subscribe(splices => this.listChanged(splices));
    }
  }

  unsubscribeItems() {
    if (this.subscription) {
      this.subscription.dispose();
      this.subscription = null;
    }
  }

  itemsChanged() {
    this.unsubscribeItems();
    this.subscribeItems();
  }

  unbind() {
    this.unsubscribeItems();
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM