观察对象数组的属性是否有任何更改

Eri*_*ith 16 javascript aurelia aurelia-binding

我正在使用Aurelia,我有一个绑定到网格的项目数组,并且它们上面有一个选定的属性.我想绑定一个按钮,当任何一个项为真时启用.我可以做一个蛮力的方法,我有一个过滤列表并返回所选项目的getter,但这意味着我将在应用程序中不断进行脏检查,我不想这样做.我希望有一个更有效的方法.有任何想法吗?

Jer*_*yow 35

你可以做的事很少 - 假设我的用例正确:

脏检查(这只是一个属性 - 不是什么大不了的事)

export class Item {
  selected = false;
}

export class ViewModel {
  items = [new Item(), new Item(), new Item()];

  get anySelected() {
    var items = this.items, i = items.length;
    while(i--) {
      if (items[i].selected) {
        return true; 
      }
    }
    return false;
  }
}
Run Code Online (Sandbox Code Playgroud)

观察物品

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

export class Item {
  selected = false;
}

@inject(BindingEngine)
export class ViewModel {
  items = [new Item(), new Item(), new Item()];    
  anySelected = false;
  subscriptions = [];

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

  updateAnySelected() {
    var items = this.items, i = items.length;
    while(i--) {
      if (items[i].selected) {
        this.anySelected = true;
        return;
      }
    }
    this.anySelected = false;
  }

  activate() {
    var items = this.items, i = items.length, observer;
    while(i--) {
      observer = this.bindingEngine.propertyObserver(items[i], 'selected');
      subscriptions.push(observer.subscribe(() => this.updateAnySelected());
    }
    this.updateAnySelected();
  }

  deactivate() {
    let dispose;
    while(subscription = subscriptions.pop()) {
      subscription.dispose();
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

使用集合类

import {computedFrom} from 'aurelia-framework';

export class Item {
  _selected = false;

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

  @computedFrom('_selected')
  get selected() {
    return this._selected;
  }
  set selected(newValue) {
    newValue = !!newValue;
    if (newValue === _selected) {
      return;
    }
    _selected = newValue;
    this.parent.itemChanged(newValue);
  }
}

export class Items {
  items = [];
  selectedCount = 0;
  anySelected = false;

  createItem() {
    let item = new Item(this);
    this.items.push(item);
    return item;
  }

  itemChanged(selected) {
    this.selectedCount += (selected ? 1 : -1);
    this.anySelected = this.selectCount > 0;    
  }
}

export class ViewModel {
  items = new Items();

  constructor() {
    let item = this.items.createItem();
    item = this.items.createItem();
    item = this.items.createItem();
  }
}
Run Code Online (Sandbox Code Playgroud)

使用selectedItems数组而不是选定的布尔prop

export class ViewModel {
  items = [{}, {}, {}];
  selectedItems = [];

  selectItem(item) {
    this.items.push(item);
  }

  deselectItem(item) {
    this.items.splice(this.items.indexOf(item), 1);
  }
}
Run Code Online (Sandbox Code Playgroud)

出于约束目的,selectedItems.length用作"任何选定"属性