少しの作業で、これを行うことができると思います。
カスタム バインディングを使用して、Raphael.js 要素をビュー モデルに接続しました。pub /sub フレームワークを使用して、canvas 要素のクリック イベント (これがあると仮定) からビュー モデルに通信できます。これにはjQuery pubsubプラグインをお勧めします。
参照用に見ることができるjsFiddleの例がありますが、ビューから離れて戻ってきた場合にキャンバス要素を破棄して再作成する必要があるという問題を示すために作成したことに注意してください。だから完璧ではない。しかし、あなたはそれの要点をつかむことができるはずです。
注目すべき重要なセクションは、html コードのカスタム バインディングです。
<div class="span10" data-bind="foreach: Current">
<div class="gauge" data-bind="createGauge: $data"></div>
</div>
カスタム バインディング js コード:
// Knockout handler to create a gauge for each bound item
ko.bindingHandlers.createGauge = {
update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
ko.utils.unwrapObservable(viewModel.updated);
var gaugeName = viewModel.Name;
var substation = bindingContext.$parent;
var gaugeObject = substation.Gauges[gaugeName];
// I cannot, for the life of me, get the gauge to redraw properly if I just
// redraw the inner. Leave the real-time values page and come back, and
// all the gauges are no longer visible.
// So destroy the existing one and recreate it from scratch.
// Yes, this is annoying!
if (gaugeObject) {
gaugeObject.gauge.removeChildren();
gaugeObject.gauge.clear();
gaugeObject.gauge.remove();
gaugeObject.gauge = null;
gaugeObject.paper.clear();
gaugeObject.paper.remove();
gaugeObject.paper = null;
gaugeObject = null;
}
if (!gaugeObject) {
var gaugeSize = $(element).height();
var paper = new Raphael(element, gaugeSize, gaugeSize);
var gauge = paper.gauge(viewModel);
gaugeObject = {
'paper': paper,
'gauge': gauge
};
substation.Gauges[gaugeName] = gaugeObject;
}
gaugeObject.gauge.updateValue(viewModel);
}
};
Raphael ゲージ コード (ここではコピーしません。長いですが、そのコードで参照されているオブザーバブルは 1 つだけであることに注意してください。そうしないと、更新されたプロパティごとにそのゲージが更新され、すべてのプロパティを更新したかったのです。ビューモデルを一度に再描画しますが、ゲージを再描画するのは 1 回のみです)。ここで、canvas 要素のクリック関数を pubsub フレームワークにフックします。
gauge.clickFunction = function ()
{
$.publish('/history', [point.IOReference]);
};
私のコードでは、それは別のビューに移動するだけですが、対応するサブスクライブ ハンドラーでは、必要に応じてビュー モデルを更新し、それをサーバーに保存し直します。