1

ノックアウトと noUiSlider をカスタム バインディングと融合させようとしています。jQuery-UI スライダーと Knockout の同様のコードを見つけ、それを基礎として使用しました。

以下のsliderkoカスタムバインディングを使用すると、noUislidersはオブザーバブルを更新しません。NaN が表示され、入力フィールドには何も表示されません。

以下のスライダー カスタム バインディングを noUiSlider イベントで直接使用すると、すべてが機能します。おそらく noUiSlider 更新イベントの追跡が原因で、スライダーのカスタム バインディングがうまく機能しません。ただし、それがスライダーで入力フィールドを継続的に更新する方法を理解できる唯一の方法です。

Knockout の registerEventHandler を使用したいのですが、それを機能させる方法がわかりません。

// noUiSlider
ko.bindingHandlers.slider = {
  init: function(element, valueAccessor, allBindingsAccessor) {
    var options = allBindingsAccessor().sliderOptions || {};
    noUiSlider.create(element, options);

    // works with with noUiSlider but not with knockout event bindings
    element.noUiSlider.on('set', function(values, handle) {
      var observable = valueAccessor();
      observable(values[handle]);
    });

    // works with with noUiSlider but not with knockout event bindings
    element.noUiSlider.on('update', function(values, handle) {
      var observable = valueAccessor();
      observable(values[handle]);
    });

    ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
      element.noUiSlider.destroy();
    });
  },
  update: function(element, valueAccessor) {
    var value = ko.utils.unwrapObservable(valueAccessor());
    element.noUiSlider.set(value);

  }
};

// using knockout event handlers
ko.bindingHandlers.sliderko = {
  init: function(element, valueAccessor, allBindingsAccessor) {
    var options = allBindingsAccessor().sliderOptions || {};
    noUiSlider.create(element, options);

    ko.utils.registerEventHandler(element, 'set', function(values, handle) {
      var observable = valueAccessor();
      observable(values[handle]);
    });

    ko.utils.registerEventHandler(element, 'update', function(values, handle) {
      var observable = valueAccessor();
      observable(values[handle]);
    });

    ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
      element.noUiSlider.destroy();
    });
  },
  update: function(element, valueAccessor) {
    var value = ko.utils.unwrapObservable(valueAccessor());
    element.noUiSlider.set(value);

  }
};

// initialization for NoUiSlider - saves from adding stuff into page
var sillysv = {
  start: [10],
  step: 0.01,
  range: {
    'min': 0,
    'max': 100
  }
};

var sillysp = {
  start: [5],
  step: 0.01,
  range: {
    'min': 0,
    'max': 100
  }
};

var ViewModel = function() {
  var self = this;
  self.savings = ko.observable();
  self.spent = ko.observable();
  self.net = ko.computed(function() {
    return self.savings() - self.spent();
  });
};

ko.applyBindings(new ViewModel());
<link href="https://cdnjs.cloudflare.com/ajax/libs/noUiSlider/8.1.0/nouislider.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/noUiSlider/8.1.0/nouislider.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<h2>Slider Demo</h2>
Savings:
<input data-bind="value: savings" />
<div style="margin: 10px" data-bind="slider: savings, sliderOptions: sillysv"></div>

Spent:
<input data-bind="value: spent" />
<div style="margin: 10px" data-bind="slider: spent, sliderOptions: sillysp"></div>

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

4

1 に答える 1