Either bind once or only when changed

Hi All,

Trying to find how to do this, but it seems not so obvious.
I see that repeat.for using an array from the viewmodel, is refreshing like crazy, while the array did not change at all.

  1. Can this either be done only when it changes
  2. If not, can I bind once using the repeat.for attribute?

<…… repeat.for=“book of booksFromMeta”>

1 Like

is booksFromMeta a computed property?

get booksFromMeta() {
}

If so, you need proper @computedFrom to avoid dirty check. https://aurelia.io/docs/binding/computed-properties#introduction

1 Like

Yes, indeed, but it is from an injected ‘service’
which has ‘getCacheMeta’

So thank you very much. This avoided refreshing
@computedFrom(‘this.config.getCacheMeta’)

However, can this be done more efficiently, e.g. on the service using the source array?

get getCacheMeta(): groupedBooks[]

{

const sorted = textWithMeta.bookEditions.sort((a,b) => a.bookid - b.bookid);

const g = groupBy(sorted, (t)=> t.bookid).map((group)=>{return {bookId: group.key, bookEditions: group.members}});

g.sort((a, b) => a.bookEditions[0].bo - b.bookEditions[0].bo)

return g;

}

1 Like

You can use computedFrom directly in service code. It works in any js object, not just view model.

@computedFrom('textWithMeta.bookEditions')
get getCacheMeta()
1 Like

Sorry, I just realized your textWithMeta. bookEditions is not from this.textWithMeta. bookEditions. The computedFrom wouldn’t work properly because it is monitoring this.textWithMeta. bookEditions.

You can either

  1. Move textWithMeta to an instance property so that it can be observed.

  2. Or, better, since your calculated value seems never change, remove the getter totally.

constructor() {
  // ...
  this.cacheMeta = this.getCacheMeta();
}

getCacheMeta() {
  //...
}
1 Like

Also noticed you have another getter in your vm, that computedFrom is still needed. Or you can avoid it by directly using config.getCacheMeta in view template.

2 Likes