在淘汰赛中消除引导开关状态的消歧

时间:2015-02-17 11:56:28

标签: javascript jquery twitter-bootstrap knockout.js bootstrap-switch

我使用bootstrap-switch以及从下面显示的question引用的淘汰赛绑定处理程序:

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数组中有一个项目数组,我可以在所有这些项目上放置一个单击处理程序,并让它们在父视图模型中调用一个函数,如下所示: / p>

data-bind="click: $parent.clickHandler"

当调用时,它会通过项目自己的视图模型。这对于获取被单击的项的属性非常方便,例如id。我在上面的小提琴中放了一个按钮来说明这是多么容易。

然而,如果我使用自举开关而不是简单的按钮,开关似乎不知道它的父母,我找不到一个优雅的方式通过包含切换到其父级的视图模型 - 就像您可以使用按钮一样。我已经尝试给数组中的每个项目引用它的父视图模型,这确实有效但创建了一个循环引用,因此看起来不是正确的方法。

2)在应用程序中,我可以在不同的客户端上更改列表中的项目状态 - 并且本地状态需要更新以反映这些远程客户端。同样,也可以在本地客户端上更改状态,然后将其传播到其他客户端。我的问题是如何消除本地发生的状态变化(即,由于用户点击交换机)和远程发生的变化(即,由于来自服务器的更新)。在我的实际项目中,我使用knockout subscribe来监听链接到交换机的值的变化,如下所示:

viewModel.observableValue.subscribe(function(newValue) {
    // test value on server and if it is different update
});

我希望避免从服务器接收更新,然后在我的交换机更改以反映新状态时再次更新服务器(具有相同的状态)。目前我通过在发送更新之前测试服务器状态(如上面的代码片段中暗示的那样)修复了这个问题,如果它与挂起状态更新相同,则我将其丢弃。 (我使用上面引用的小提琴中的按钮模拟了服务器更新。)

我对这些问题的解决方案都没有感觉优雅,因此这里的问题。 任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

  1. 我不确定你的意思是'开关似乎不知道它的父母'。查看http://knockoutjs.com/documentation/custom-bindings.html,我可以看到initupdate都有第5个参数,bindingContext有父信息,如果您想访问它。
  2. Ahem,我们过去工作的其中一个项目有一个切换按钮,它遇到了同样的问题并且修复了它是一种非常简单的方法。对于在本地生成的事件,只需将属性附加到对象(如.local = true;)并在更新中检查它(或将其附加到REST处理程序中)以区分本地/与REST。不过忘记在更新完成后从视图模型中删除属性。