#knockout.js #jquery-ui-selectable
#knockout.js #jquery-выбираемый пользовательский интерфейс
Вопрос:
Я пытаюсь использовать функциональность списка выбора jQuery при использовании KnockoutJS, но не могу заставить его работать.
Используя пользовательские привязки, мне удалось преобразовать ul
элемент в выбираемый и создать обработчики событий для выбранных и невыбранных событий. Но что мне передать моим функциям ViewModel, которые поддерживают выбранные элементы?
Вот мой код до сих пор: http://jsfiddle.net/QCmJt /
Я новичок во всем этом, поэтому, возможно, я неправильно подхожу к этому…
Ответ №1:
Вот немного измененный вариант вашего, он тоже работает. Он использует свойство selected для каждого элемента в массиве, которое является наблюдаемым для двусторонней связи. Если вам нужно свойство, представляющее собой просто список выбранных элементов, вы всегда можете создать зависимую наблюдаемую или просто метод для фильтрации.
Создана пользовательская привязка:
ko.bindingHandlers.selectableItem = {
init: function(element, valueAccessor, allBindingsAccessor) {
var selectable = $(element).parent();
selectable.bind('selectableselected', function(event, ui) {
if(ui.selected === element) {
var value = valueAccessor();
value(true);
}
});
selectable.bind('selectableunselected', function(event, ui) {
if(ui.unselected === element) {
var value = valueAccessor();
value(false);
}
});
},
update: function(element, valueAccessor, allBindingsAccessor, viewModel) {
var el = $(element);
if(valueAccessor()()) {
el.addClass('ui-selected');
} else {
el.removeClass('ui-selected');
}
}
};
Он не предназначен для более чем очень простых двухсторонних привязок, но должен быть достаточно простым в построении.
Комментарии:
1. Спасибо, Пол! Это хороший способ приблизиться к этому. Меня беспокоит только смешивание статуса выбора строки пользовательского интерфейса в свойстве модели представления «запросы». В моем сценарии свойство ‘requests’ синхронизируется обратно с серверной частью, и поэтому я предпочитаю использовать другое свойство для сохранения статуса выбранной строки.
2. @joerage Да, я знаю, что ты имеешь в виду. Я видел, как вы его представили, и попытался заставить его работать таким образом, но не повезло. Вы должны рассматривать это как MVVM, поскольку это цель Knockout. В MVVM ViewModel является абстракцией представления и гораздо более тесно связана с пользовательским интерфейсом, не обязательно с объектами вашего домена, поэтому имеет смысл, что если эти объекты пользовательского интерфейса имеют свойство, указывающее статус выбора, которое отражается в ViewModel. Если вам нужно, чтобы это представление отличалось для сохранения, вы всегда можете переназначить объекты на сервере.
Ответ №2:
Хорошо, я нашел способ передать данные, привязанные к выбранному элементу:
$(ui.selected).tmplItem().data
при выборе и $(ui.selected).tmplItem().data
при отмене выбора.
Вот обновленная скрипка: http://jsfiddle.net/8RnxC /
Пользовательская привязка выглядит следующим образом:
ko.bindingHandlers.selectable = {
init: function(element, valueAccessor) {
$(element).attr("id", "selectable").selectable({
selected: function(event, ui) {
vm.selectRequest($(ui.selected).tmplItem().data);
},
unselected: function(event, ui) {
vm.unselectRequest($(ui.unselected).tmplItem().data);
}
});
}
};
И моя модель представления:
function viewModel() {
// Data
this.requests = ko.observableArray([]);
this.selectedRequests = ko.observableArray([]);
// Behaviours
this.selectRequest = function(request) {
this.name = "othername";
// Add to array if not already there.
if ($.inArray(request, this.selectedRequests()) === -1) {
this.selectedRequests().push(request);
}
var self = this;
};
this.unselectRequest = function(request) {
// Remove from the array.
this.selectedRequests().splice($.inArray(request, this.selectedRequests()), 1);
};
};