使用带有jquery ui滑块的knockout js

时间:2012-10-12 09:30:07

标签: jquery-ui knockout.js

我正在试图找出淘汰赛js是否可以很好地解决以下问题:

我有多个滑块,我想链接到文本框。

更改文本框时,相应的滑块必须更新为新值,反之亦然。

在更改滑块值或文本框时,需要调用一个函数,该函数使用所有文本框中的输入来计算结果。

我有快速而又脏的jQuery解决方案here

使用knockout js以更优雅的方式实现相同的结果是否容易?

我想我需要创建一个自定义绑定处理程序,就像它在jQuery UI datepicker change event not caught by KnockoutJS

中完成的那样

4 个答案:

答案 0 :(得分:36)

以下是一个示例:http://jsfiddle.net/jearles/Dt7Ka/

我使用自定义绑定来集成jquery-ui滑块,并使用Knockout捕获输入并计算净额。

-

UI

<h2>Slider Demo</h2>

Savings: <input data-bind="value: savings, valueUpdate: 'afterkeydown'" />
<div style="margin: 10px" data-bind="slider: savings, sliderOptions: {min: 0, max: 100, range: 'min', step: 1}"></div>

Spent: <input data-bind="value: spent, valueUpdate: 'afterkeydown'" />
<div style="margin: 10px" data-bind="slider: spent, sliderOptions: {min: 0, max: 100, range: 'min', step: 1}"></div>

Net: <span data-bind="text: net"></span>

查看模型

ko.bindingHandlers.slider = {
  init: function (element, valueAccessor, allBindingsAccessor) {
    var options = allBindingsAccessor().sliderOptions || {};
    $(element).slider(options);
    $(element).slider({
        "slide": function (event, ui) {
            var observable = valueAccessor();
            observable(ui.value);
        },
        "change": function (event, ui) {
            var observable = valueAccessor();
            observable(ui.value);
        }
    });
    ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
        $(element).slider("destroy");
    });
  },
  update: function (element, valueAccessor) {
    var value = ko.unwrap(valueAccessor());
    if (isNaN(value)) {
        value = 0;
    }
    $(element).slider("value", value);
  }
};

var ViewModel = function() {
    var self = this;

    self.savings = ko.observable(10);
    self.spent = ko.observable(5);
    self.net = ko.computed(function() {
        return self.savings() - self.spent();
    });
}

ko.applyBindings(new ViewModel());

答案 1 :(得分:9)

我知道这是几天前,但我对John Earles代码进行了一些调整:

ko.bindingHandlers.slider = {
init: function (element, valueAccessor, allBindingsAccessor) {
    var options = allBindingsAccessor().sliderOptions || {};
    $(element).slider(options);
    ko.utils.registerEventHandler(element, "slidechange", function (event, ui) {
        var observable = valueAccessor();
        observable(ui.value);
    });
    ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
        $(element).slider("destroy");
    });
    ko.utils.registerEventHandler(element, "slide", function (event, ui) {
        var observable = valueAccessor();
        observable(ui.value);
    });
},
update: function (element, valueAccessor, allBindingsAccessor) {
    var value = ko.utils.unwrapObservable(valueAccessor());
    if (isNaN(value)) value = 0;
    $(element).slider("option", allBindingsAccessor().sliderOptions);
    $(element).slider("value", value);
}
};

原因是如果你使用改变的选项(fx另一个可观察的),那么即使你想要它也不会影响滑块。

答案 2 :(得分:2)

@John Earles和@Michael Kire Hansen:感谢您的精彩解决方案!

我使用了Michael Kire Hansen的高级代码。我把&#34; max:&#34;滑块选项为ko.observable,结果表明滑块在这种情况下没有正确更新值。示例:假设滑块位于25的最大值25,并且您将最大值更改为100,滑块保持在最右侧位置,表示它处于最大值(但值仍为25,而不是100)。只要向左滑动一个点,就会将值更新为99。

解决方案: 在&#34;更新:&#34;部分只是将最后两行切换为:

$(element).slider("option", allBindingsAccessor().sliderOptions);
$(element).slider("value", value);

首先更改选项,然后更改值,它就像魅力一样。

答案 3 :(得分:0)

非常感谢你的帮助,我需要在我的场景中使用范围滑块,所以这里是@John Earles和@Michael Kire Hansen的扩展

ko.bindingHandlers.sliderRange = {
init: function (element, valueAccessor, allBindingsAccessor) {
    var options = allBindingsAccessor().sliderOptions || {};
    $(element).slider(options);
    ko.utils.registerEventHandler(element, "slidechange", function (event, ui) {
        var observable = valueAccessor();
        observable.Min(ui.values[0]);
        observable.Max(ui.values[1]);
    });
    ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
        $(element).slider("destroy");
    });
    ko.utils.registerEventHandler(element, "slide", function (event, ui) {
        var observable = valueAccessor();
        observable.Min(ui.values[0]);
        observable.Max(ui.values[1]);
    });
},
update: function (element, valueAccessor, allBindingsAccessor) {
    var value = ko.utils.unwrapObservable(valueAccessor());
    if (isNaN(value.Min())) value.Min(0);
    if (isNaN(value.Max())) value.Max(0);

    $(element).slider("option", allBindingsAccessor().sliderOptions);
    $(element).slider("values", 0, value.Min());
    $(element).slider("values", 1, value.Max());
}
};

然后是随附的HTML

<div id="slider-range" 
             data-bind="sliderRange: { Min: 0, Max: 100 }, 
                                sliderOptions: { 
                                    range: true,
                                    min: 0,
                                    max: 100,
                                    step: 10,
                                    values: [0, 100]
                                }"></div>