knockoutjs

knockout.jsのObservableArrayで項目の変更でも通知する

More than 1 year has passed since last update.

2017-12-01追記

obsArray.notifySubscribers()

でよかった…。
knockout-es5を使っていたせいでハマっていたようだ。

ko.getObservable(this, 'obsArray').notifySubscribers()

とすることで、knockout-es5を使っていても強制通知を行うことができた。
以降の内容はログとして残しておくけれど、意味はなさそう…。

ObservableArrayの通知は配列への追加・削除などのみ

ObservableArrayの配列のアイテムの変更を行っても、ko.computedで検知してくれなかった。このため、変更が行われているにも関わらず、何も起きない…。

中身を変更しても検知しないが、強制通知する方法があるだろうと探して見たものの、どうも公式な方法では、なさそうだった。

強制通知を実装する

stack overflowでヒットした。

Refresh observableArray when items are not observables

どうするかというと、変更のあったアイテムを削除し、再度追加するという方法だった。ObservableArrayは、追加・削除は通知されるので、これならば通知が発生する。

changedIdx = obsArray.indexOf(changedItem)
obsArray.splice(changedIdx , 1) # アイテムを削除
obsArray.splice(changedIdx , 0, changedItem) # 再度追加

カスタム関数を追加

毎度毎度この処理を実行するのは大変なので、カスタム関数を定義する。

ko.observableArray.fn.refresh = (item) ->
  changedIndex = this.indexOf(item)
  if changedIndex >= 0
    this.splice(changedIndex, 1)
    this.splice(changedIndex, 0, item)

これで、observableArray.refresh(item)と呼び出すだけで変更通知が行われる様になる。