在 Aurelia 中观察数组属性

Observing Array Properties in Aurelia

我的 class 上有一个 属性:

class Control {
    @bindable households;

    get people() {
        return households
            .map(household => househould.people)
            .reduce((g1, g2) => g1.concat(g2), []);
    }
}

我用它来计算所有家庭中所有 people[] 的集合,然后在此处呈现:

<ul>
    <li repeat.for="person of people">
        ${person.firstName} ${person.lastName} - ${person.phone}
    </li>
</ul>

我需要列表在有人添加到家庭时更新,或者如果任何渲染属性 firstNamelastNamephone 中的任何元素计算集合已更新。我怎样才能在 Aurelia 做到这一点?如果我使用 @computedFrom() 它不会检测到数组元素的变化,并且由于所有家庭中的人员列表是动态的,我不能只为每个元素创建一个观察者而不创建一个系统来管理观察者何时应该已订阅/未订阅。

就在我即将放弃能够Google寻求解决方案时,Aurelia Signaling came to the rescue。这段代码最终对我有用:

<ul>
    <li repeat.for="person of people">
        <!-- May work without this rendering method,
            this is just closer to what my actual code is doing. -->
        ${renderPersonInfo(person) & signal: 'example-signal'}
    </li>
</ul>

和 class:

import {BindingSignaler} from 'aurelia-templating-resources';

@inject(BindingSignaler)
class Control {
    @bindable households;

    constructor(bindingSignaler) {
        this.bindingSignaler = bindingSignaler;
        //Obviously, you can have this trigger off any event
        setInterval(() => this.bindingSignaler.signal('example-signal'), 1000);
    }

    get people() {
        return households
            .map(household => househould.people)
            .reduce((g1, g2) => g1.concat(g2), []);
    }
}

使用脏检查

停止 @computedFrom(),您将获得所需的行为。

export class App {
  @bindable households;
  get people() {
    const households = this.households || []; // Make sure househoulds is defined.
    return households.reduce((people, household) => people.concat(household.people), []);
  }
}

https://gist.run/?id=040775f06aba5e955afd362ee60863aa

您必须尽可能避免 dirty-checking,信号是您场景的完美选择。请记住,如果你想在数组上使用 computedFrom,你可以通过观察它的 length 属性 而不是 dirtyChecking 来实现,例如下面的 @computedFrom("myArray.length")