【问题标题】:Knockout model + jQuery UI range slider淘汰赛模型 + jQuery UI 范围滑块
【发布时间】:2014-12-23 02:01:58
【问题描述】:

我正在使用 Knockout 模型,我希望使用 jQuery UI 范围滑块更新此模型中的值。考虑以下示例:

型号:

var ViewModel = function () {
    var self = this;
    self.MinTerm = ko.observable();
    self.MaxTerm = ko.observable();
}

ko.applyBindings(new ViewModel());

现在,jQuery UI 范围滑块应该更新这两个值。这个(非常丑陋的)解决方案接近了,我的 ViewModel 中的值正在更新,但不知何故这并没有反映在绑定到这些值的控件中,例如:

HTML

<div id="sliderTerms"></div>
<span data-bind="text: MinTerm"></span>
<span data-bind="text: MaxTerm"></span>

脚本:

    $("#sliderTerms").slider({
        range: true,
        min: 6,
        max: 120,
        values: [6, 120],
        step: 1,
        slide: function (event, ui) {
            ViewModel.MinTerm = ui.values[0];
            ViewModel.MaxTerm = ui.values[1];
        }
    });

现在,如果我可以绑定到这样的自定义 bindingHandler,那就太好了,它非常适合将滑块绑定到我的 KO 模型中的奇异值:

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) {
        var value = ko.utils.unwrapObservable(valueAccessor());
        if (isNaN(value)) value = 0;
        $(element).slider("value", value);

    }
};

这就是我卡住的地方。例如,是否可以分配一个 valueAccessors 数组,这样我就可以执行以下操作:

<div id="sliderTerms" data-bind="rangeSlider: [MinTerm, MaxTerm], sliderOptions: {min: 6, max: 120, range: true, step: 1}"></div>

谢谢!

【问题讨论】:

    标签: jquery jquery-ui knockout.js


    【解决方案1】:

    我根据你的写了自己的,它是一个快速的模型,所以它可能有错误

    http://jsfiddle.net/N9uwx/

    ko.bindingHandlers.slider = {
        init: function (element, valueAccessor, allBindingsAccessor) {
            var options = allBindingsAccessor().sliderOptions || {};
            var observable = valueAccessor();
    
            if(observable().splice) {
                options.range = true;        
            }        
    
            options.slide = function(e, ui) {
                observable(ui.values ? ui.values : ui.value);
            };
    
            ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
                $(element).slider("destroy");
            });
    
            $(element).slider(options);
        },
        update: function (element, valueAccessor) {
            var value = ko.utils.unwrapObservable(valueAccessor());
            $(element).slider(value.slice ? "values" : "value", value);
    
        }
    };
    

    【讨论】:

      【解决方案2】:

      谢谢!您的代码启发了我编写这个 bindingHandler:

      ko.bindingHandlers.rangeSlider = {
          init: function (element, valueAccessor, allBindingsAccessor) {
              var options = allBindingsAccessor().sliderOptions || {};
              var observable = valueAccessor();
      
              ko.utils.registerEventHandler(element, "slidechange", function (event, ui) {
                  observable[0](ui.values[0]);
                  observable[1](ui.values[1]);
              });
              ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
                  $(element).slider("destroy");
              });
              ko.utils.registerEventHandler(element, "slide", function (event, ui) {
                  observable[0](ui.values[0]);
                  observable[1](ui.values[1]);
              });
      
              $(element).slider(options);
          },
          update: function (element, valueAccessor) {
              var value = ko.utils.unwrapObservable(valueAccessor());
               if(value instanceof Array)
              {
                  var value1= ko.utils.unwrapObservable(value[0]);
                  var value2= ko.utils.unwrapObservable(value[1]);
                  if(value1)
                  {
                      value = [value1, value2];
                  }
                  else value = 0;
              }
              else if (isNaN(value)) value = 0;
              $(element).slider(value.slice ? "values" : "value", value);
          }
      }; 
      

      现在我可以像这样将 rangeSlider 绑定到我的 Knockout 模型:

      <div id="sliderTerms" data-bind="rangeSlider: [MinTerm, MaxTerm], sliderOptions: {min: 6, max: 120, range: true, step: 1, values: [6,120]}"></div>
      

      有点臭,因为我认为 values[i] 应该绑定到 valueAccessor[i] 但这对我来说已经足够了。

      【讨论】:

      • 我更新了我的因为另一个 SO 问题stackoverflow.com/questions/13682691/…
      • 发现一个错误,如果我更改绑定到范围滑块的模型中的值,滑块值不会被更新。将发布修复(如果我找到了..)
      • 还没弄明白,这里有一个演示“挑战”的小提琴:jsfiddle.net/adr8G
      【解决方案3】:

      对于@Nico Beemster 在他自己的代码中发现的错误,我们需要“更新”更新:像这样的部分:

       update: function (element, valueAccessor, allBindingsAccessor) {
                  console.log("update fired");
                  var value = ko.utils.unwrapObservable(valueAccessor());
                    if(value instanceof Array)
              {
                  var value1= ko.utils.unwrapObservable(value[0]);
                  var value2= ko.utils.unwrapObservable(value[1]);
                  if(value1)
                  {
                      value = [value1, value2];
                  }
                  else value = 0;
              }
              else if (isNaN(value)) value = 0;
                  $(element).slider(value.slice ? "values" : "value", value);
                   $(element).slider("option", allBindingsAccessor().sliderOptions);
              }
      

      here 是更新后的小提琴。如果您想更新最大和最小范围元素(如果它们是可观察元素)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-11-20
        • 2012-10-03
        • 1970-01-01
        • 2016-02-29
        • 2013-11-25
        • 1970-01-01
        • 2014-04-08
        • 1970-01-01
        相关资源
        最近更新 更多