我确实认为您可以通过一些工作来做到这一点。
我已经使用自定义绑定将 Raphael.js 元素连接到视图模型,并且您可以使用 pub/sub 框架从画布元素单击事件(假设它具有此事件)与您的视图模型进行通信。我会为此推荐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 仪表代码(我不会在这里复制它,它很长,但请注意我在该代码中只引用了一个 observable,否则该仪表将针对每个更新的属性进行更新,我想更新所有属性一口气在视图模型上,但只有仪表重绘一次),我将画布元素的点击功能挂钩到 pubsub 框架:
gauge.clickFunction = function ()
{
$.publish('/history', [point.IOReference]);
};
在我的代码中,它只导航到不同的视图,但在相应的订阅处理程序上,您可以根据需要更新视图模型并将其保存回服务器。