2012-11-30 47 views
0

我正在使用Knockout模型,并且希望使用jQuery UI范围滑块更新此模型中的值。请看下面的例子:Knockout模型+ jQuery UI范围滑块

型号:现在

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

ko.applyBindings(new ViewModel()); 

,一个jQuery UI范围滑块应更新这两个值。这(非常丑陋)解决方案走近,在我的视图模型中的值被更新,但不知何故,这并没有反映在绑定到这些值的控制,如:

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> 

谢谢!

回答

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); 

    } 
}; 
0

谢谢!您的代码启发我写这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绑定到我的淘汰赛模式是这样的:

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

这是一个有点臭,因为我认为值[I]应该绑定valueAccessor [i],但这对我来说已经足够了。

+0

我更新了我的另一个SO问题http://stackoverflow.com/questions/13682691/knockout-js-jquery-range-slider-2-inputs/13683657#13683657 – Anders

+0

发现了一个错误,如果我改变一个值在绑定到范围滑块的模型中,滑块值不会被更新。将发布修复(如果我找到一个..) –

+0

嗯,“更新”事件没有被解雇。 –

0

为@Nico的Beemster在自己的代码中发现的bug,我们需要“更新”更新:一部分是这样的:

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是更新的小提琴。如果你想更新最大和最小范围元素,如果他们是可观察元素。