如何使用knockout.js正确绑定和初始化jQuery Mobile范围滑块?

时间:2013-05-11 11:21:11

标签: jquery-mobile knockout.js custom-binding rangeslider

我有一些麻烦让JQM范围滑块适用于淘汰赛。 这是JQM滑块的一个非常基本的html代码:

<input type="range" name="quantity-slider" id="quantity-slider" min="0" max="10">

我已经创建了这个敲除绑定的示例,应用于文档就绪:

var ViewModel = function() {
    this.quantity = ko.observable(4);
}

$(document).ready(function () {
    ko.applyBindings(new ViewModel());
});

我在互联网上阅读了一些来自其他人的帖子,这些帖子也发现了与范围滑块的JQM初始化相关的一些问题(例如:http://css.dzone.com/articles/knockoutjs-binding-helper和此处:http://www.programico.com/1/post/2012/12/knockoutjs-jquerymobile-slider.html)并提供了工作解决方案,每个都有自己的自定义绑定实现。

其中一个,如下(http://www.hughanderson.com/):

data-bind="value: quantity, slider: quantity"

到目前为止,这么好。在那之后,我遇到了这个问题:

如果JQM滑块位于第一页,则可以正常工作。当JQM滑块位于第二页时,不再起作用。

我认为这是一个与这个特殊的JQM小部件及其DOM操作相关的问题,我可以理解。为了更好地解释这一点,我已经制作了两个jsFiddle,其中我只是交换了两个JQM页面的顺序:

  1. 无效:第二个JQM页面上的http://jsfiddle.net/5q38Q/滑块
  2. 工作:第一个JQM页面上的http://jsfiddle.net/5q38Q/1/滑块
  3. 有人可以解释一下,这是初始化JQM滑块的敲除绑定的正确方法吗?也许有另一种方法为JQM滑块编写自定义绑定,或者敲除绑定应该放在pagebeforeshow事件中?

    更新 通过以下更改,滑块显示正确的值,并与文本输入部分同步:

    $(document).on('pagebeforeshow', '#slider-page', function(){       
        $('#quantity-slider').val(viewModel.quantity());
        $('#quantity-slider').slider('refresh');
    });
    

    但我想知道是否没有更好的解决方案。

    至少,与Varun的自定义绑定一起,它现在对我很有效!

3 个答案:

答案 0 :(得分:2)

我遇到了同样的问题。这就是我解决它的方式。虽然在使用文本输入直接编辑值时,此解决方案不会更新observable。 (我没有显示输入文本框,所以这个解决方案对我来说已经足够了)

http://jsfiddle.net/WMr8D/9/

$(document).ready(function () {
var ViewModel = function () {
    var self = this;
    self.quantity = ko.observable(4);
};    

ko.bindingHandlers.slider = {
    init: function (element, valueAccessor) {
        var value = valueAccessor();
        $(document).on({
            "mouseup touchend keypress": function (elem) {
                value($('#' + element.id).val());
            }
        }, ".c-slider");
    }
};    

ko.applyBindings(new ViewModel());
});

答案 1 :(得分:1)

花了几个小时来测试网络上关于这个问题的所有变化,我最终得到了以下解决方案,也许这有助于其他人的业余时间:

最后的工作小提琴: http://jsfiddle.net/CT7fy/

问题是关于如何将knockout.js和JQuery Mobile滑块与多页导航集成,我认为这将是最常见的情况之一。

所以我很抱歉,我不能认为Varun的答案是完整和令人满意的,但我必须说,如果没有 Varun的自定义绑定处理程序,我将永远找不到一个可行的解决方案。

这是自定义绑定处理程序,slighlty modified:

/* custom binding handler thanks to Varun http://stackoverflow.com/a/16493161/2308978 */
ko.bindingHandlers.slider = {
    init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        var value = valueAccessor();
            $(document).on({
                "mouseup touchend keypress": function (elem) {
                var sliderVal = $('#' + element.id).val();
                value(sliderVal);
            }
        }, ".ui-slider");
    }
 };

...这是页面初始化:

$(document).on('pagebeforeshow', '#slider-page', function(){
    $('#quantity-slider').val(viewModel.quantity());
    $('#quantity-slider').slider('refresh');
});

在您输入或标签后,滑块的文本部分也会同步,因为这是标准滑块行为。

答案 2 :(得分:0)

在自定义处理程序中,绑定到&#34;更改&#34;更可靠。事件比绑定到mouseup touchend和keypress。此外,pagebeforeshow事件也不是必需的。您可以在处理程序中的init期间设置value属性:

ko.bindingHandlers.slider = {
    init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        var value = valueAccessor();
        $(element).attr("value", value());
            $(document).on({
                "change": function (elem) {
                var sliderVal = $('#' + element.id).val();
                value(sliderVal);
            }
        }, ".ui-slider");
    }
 };

参见示例:http://jsfiddle.net/ZbrB7/2483/