[英]Disambiguating bootstrap-switch state changes in knockout
我正在使用bootstrap-switch以及从以下所示问题中引用的敲除绑定处理程序:
ko.bindingHandlers.bootstrapSwitchOn = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
$elem = $(element);
$elem.bootstrapSwitch();
// Set intial state
$elem.bootstrapSwitch('setState', ko.utils.unwrapObservable(valueAccessor()));
$elem.on('switch-change', function (e, data) {
// Update the model when changed.
valueAccessor()(data.value);
});
},
update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
var vStatus = $(element).bootstrapSwitch('status');
var vmStatus = ko.utils.unwrapObservable(valueAccessor());
if (vStatus != vmStatus) {
$(element).bootstrapSwitch('setState', vmStatus);
}
}
};
这似乎工作得很好,并且我已经模拟了一个小提琴来说明我如何在这里使用它:
http://jsfiddle.net/swervo/of0q42j0/5/
但是,我有一些问题似乎无法令人满意地解决:
1)如果我在ko.observable数组中有一个项目数组,则可以在所有项目上放置一个点击处理程序,并让它们在父视图模型中调用函数,如下所示:
data-bind="click: $parent.clickHandler"
调用时,将通过项目自己的视图模型。 这对于获取被单击项的属性(例如ID)确实非常方便。 我在上方的小提琴中放置了一个按钮,以说明这样做很容易。
但是,如果我使用的是bootstrap-switch而不是简单的按钮,则该开关似乎不知道它是父级的,并且我找不到一种优雅的方式将包含该开关的视图模型传递给它的父级-你可以用一个按钮。 我尝试给数组中的每个项目提供对其父视图模型的引用,这确实起作用,但是创建了循环引用,因此似乎不是正确的方法。
2)在我正在构建的应用程序中,可以在其他客户端上更改列表中项目的状态-并且需要更新本地状态以反映这些远程客户端。 同样,状态也可以在本地客户端上更改,然后传播到其他客户端。 我的问题是如何区分本地发生的状态更改(即,由于用户单击了开关)和远程发生的更改(即,由于来自服务器的更新)。 在我的实际项目中,我使用敲除订阅来侦听链接到开关的值的更改,如下所示:
viewModel.observableValue.subscribe(function(newValue) {
// test value on server and if it is different update
});
我要避免从服务器接收更新,然后在我的开关更改以反映新状态时再次更新服务器(具有相同的状态)。 目前,我已经通过在发送更新之前测试服务器状态(如上面的代码片段中所暗示的)来解决此问题,并且如果它与未决状态更新相同,则将其丢弃。 (我已经使用上面引用的小提琴中的按钮模拟了服务器更新)。
我对这些问题的解决方案都不是优雅的,因此这里是一个问题。 任何帮助将非常感激。
init
和update
都具有第五个参数, bindingContext
具有父信息,如果您希望访问它的话。 .local = true;
并在更新中进行检查(或将其附加到您的REST处理程序中)以区分本地/ VS REST。 不过,一旦更新完成,别忘了从视图模型中删除该属性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.