在更改为包含数组时更新Aurelia观察到的属性

con*_*adj 3 javascript aurelia aurelia-binding

我有一个简单的类,Event具有计算属性:

import moment from 'moment';

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

    get playedFromNow() { 
        return moment(this.CreateDate).fromNow();
    }
}
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

和(相关)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();
Run Code Online (Sandbox Code Playgroud)

目前该属性是脏的检查,这意味着该属性被检查并经常更改 - 这是有点不必要的,屏幕上显示了很多事件,所以我担心随着时间的推移性能.有没有办法可以根据数组绑定触发重新计算并更新VM中的代码?:

Jer*_*yow 10

最新的aurelia版本有一个新功能: 绑定行为将有助于此用例.

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

从-now.js

import moment from 'moment';

export class FromNowValueConverter {
  toView(date) {
    return moment(date).fromNow();
  }
}
Run Code Online (Sandbox Code Playgroud)

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

更改${event.playedFromNow}到:

${event.CreateDate | fromNow & signal:'tick'}
Run Code Online (Sandbox Code Playgroud)

简单地说,这个绑定说,使用fromNow转换器转换日期值,并在tick发出信号时刷新绑定.

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

<!-- this goes at the top of any view using the FromNowValueConverter -->
<require from="./from-now"></require>
Run Code Online (Sandbox Code Playgroud)

最后,让我们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);
  }
}
Run Code Online (Sandbox Code Playgroud)