Использование нокаута js с ползунками jquery ui

Я пытаюсь выяснить, будет ли нокаут js работать хорошо для следующей проблемы:

У меня есть несколько слайдеров, которые я хочу связать с текстовыми полями.

При изменении текстового поля соответствующий слайдер должен обновиться до нового значения и наоборот.

При изменении значения ползунка или текстового поля необходимо вызвать функцию, которая использует ввод из всех текстовых полей для вычисления результата.

У меня есть мое быстрое и грязное решение jQuery.

Было бы легко добиться того же результата более элегантным способом с помощью нокаута js?

Я предполагаю, что мне нужно будет создать собственный обработчик привязки, как это сделано в jQuery UI datepicker change event, не пойманный KnockoutJS

Вот пример: http://jsfiddle.net/jearles/Dt7Ka/

Я использую настраиваемую привязку для интеграции слайдера jquery-ui и использую Knockout для захвата входов и вычисления чистой суммы.

UI

Slider Demo

Savings:
Spent:
Net:

Просмотр модели

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

Я знаю, что это было несколько дней назад, но я внес несколько изменений в код Джона Эрлса:

 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 другой наблюдаемый), то это не повлияет на слайдер, даже если вы этого захотите.

@John Earles и @Michael Kire Hansen: спасибо за ваши замечательные решения!

Я использовал расширенный код от Michael Kire Hansen. Я привязал опцию «max:» ползунка к ko.observable, и оказалось, что слайдер неправильно обновляет значение в этом случае. Пример. Предположим, что ползунок имеет значение 25 макс. 25, и вы изменяете максимальное значение до 100, ползунок остается в самом правом положении, указывая, что он находится на максимальном значении (но значение все равно 25, а не 100). Как только вы сдвинете одну точку влево, вы получите значение, обновленное до 99.

Решение: в разделе «update:» просто переключите последние две строки на:

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

Это сначала меняет параметры, затем значение и работает как шарм.

Большое спасибо за помощь, мне нужно было использовать слайдер диапазона в моем сценарии, так что это расширение для @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 для сопровождения

 
  • Ошибка Catch, если iframe src не загружается. Ошибка: - «Отказано для отображения» http://www.google.co.in/ «в кадре».
  • Knockout.js без контейнера «foreach» не работает с
  • Возврат частичного просмотра и JSON из ASP.NET MVC Action
  • Получение «Запрос JSON был слишком большим для десериализации»
  • Проверка нокаута
  • Можете ли вы вызвать ko.applyBindings, чтобы связать частичный просмотр?
  • Загрузочный твиттер 3 Модаль с нокаутом
  • Давайте будем гением компьютера.