观察对象数组的属性是否有任何变化 [英] Observe property on an array of objects for any changes

查看:27
本文介绍了观察对象数组的属性是否有任何变化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am using Aurelia and I have an array of items bound to a grid and they have a selected property on them. I want to bind a button to be enabled when any one of the items is true. I can do a brute force approach where I have a getter that is filtering the list and returning the selected items, but that means that I would be doing dirty checking constantly in the app and I don't want to do that. I am hoping for a more efficient approach. Any ideas?

推荐答案

你可以做的事情很少 - 假设我有你的用例:

Few things you could do- assuming I have your use case right:

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;
  }
}

观察物品

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();
    }
  }
}

使用集合类

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();
  }
}

使用 selectedItems 数组代替选定的布尔属性

use a selectedItems array instead of a selected boolean prop

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

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

  deselectItem(item) {
    this.items.splice(this.items.indexOf(item), 1);
  }
}

出于绑定目的,使用 selectedItems.length 作为您的任何选定"属性

for binding purposes, use selectedItems.length as your "any selected" property

这篇关于观察对象数组的属性是否有任何变化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆