我有一个简单的类Event
,带有计算属性:
import moment from 'moment';
export class Event {
constructor(data) {
Object.assign(this, data);
}
get playedFromNow() {
return moment(this.CreateDate).fromNow();
}
}
playedFromNow
只返回基于CreateDate
属性的字符串,例如7 minutes ago
。
viewmodel获取一系列事件,视图呈现事件。每次发生新事件时(每隔几分钟),数组就会通过websockets进行更新。
<div repeat.for="event of events">
<div class="media-body">
<h4 class="media-heading">${event.title} <small>${event.playedFromNow}</small></h4>
</div>
</div>
和(相关)viewmodel代码:
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();
目前该属性已经过脏检查,这意味着该属性被检查并且频繁更改 - 这有点不必要,并且屏幕上显示了很多事件,因此我关注一段时间内的性能。有没有办法可以根据数组中的数组绑定和更新代码触发重新计算?:
答案 0 :(得分:10)
最新的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);
}
}