更新 Aurelia 观察到 属性 对包含数组的更改

Update Aurelia observed property on change to containing array

我有一个简单的 class, Event 和计算 属性:

import moment from 'moment';

export class Event {
    constructor(data) {
        Object.assign(this, data);
    }

    get playedFromNow() { 
        return moment(this.CreateDate).fromNow();
    }
}

playedFromNow 只是 returns 基于 CreateDate 属性 的字符串,例如 7 minutes ago.

视图模型获取事件数组,视图呈现事件。每次发生新事件时(每隔几分钟),数组都会通过 websockets 更新。

<div repeat.for="event of events">
    <div class="media-body">
        <h4 class="media-heading">${event.title} <small>${event.playedFromNow}</small></h4>
    </div>
</div>

以及(相关的)视图模型代码:

let  socket = io();
socket.on(`new-event`, (data) => { 
  this.events.unshift(new Event(data)); // add to the event array at the top
});

// subscribe
let subscription = bindingEngine.collectionObserver(this.events).subscribe();
// unsubscribe
subscription.dispose();

目前 属性 已被检查,这意味着 属性 已被检查并且更改非常频繁 - 这有点不必要,屏幕上显示了很多事件,所以我'我担心随着时间的推移表现。有什么方法可以触发基于数组绑定的重新计算和VM中的更新代码吗?:

最新的 aurelia 版本有一个新功能:binding behaviors 这将有助于此用例。

第一步是从视图模型中删除 playedFromNow 属性。我们将把逻辑放在值转换器中以消除脏检查并使逻辑能够在其他视图中重用:

从-now.js

import moment from 'moment';

export class FromNowValueConverter {
  toView(date) {
    return moment(date).fromNow();
  }
}

现在让我们更新我们的视图以使用值转换器以及内置的 signal 绑定行为。使用 signal 我们将能够告诉绑定何时刷新。

${event.playedFromNow}更改为:

${event.CreateDate | fromNow & signal:'tick'}

此绑定用简单的英语表示,使用 fromNow 转换器转换日期值,并在发出 tick 信号时刷新绑定。

不要忘记在视图顶部导入值转换器:

<!-- this goes at the top of any view using the FromNowValueConverter -->
<require from="./from-now"></require>

最后,让我们定期...每分钟触发 tick 信号?

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

@inject(BindingSignaler)
export class App {  
  constructor(signaler) {
    // refresh all bindings with the signal name "tick" every minute:
    setInterval(() => signaler.signal('tick'), 60 * 1000);
  }
}