Commit bfa88e43 authored by David Stutz's avatar David Stutz

Merge pull request #447 from Aaron-P/master

Improved knockout binding.
parents 614bd4b5 3f1b6be7
...@@ -11,71 +11,82 @@ ...@@ -11,71 +11,82 @@
if (typeof ko !== 'undefined' && ko.bindingHandlers && !ko.bindingHandlers.multiselect) { if (typeof ko !== 'undefined' && ko.bindingHandlers && !ko.bindingHandlers.multiselect) {
ko.bindingHandlers.multiselect = { ko.bindingHandlers.multiselect = {
after: ['options', 'value', 'selectedOptions'],
init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
var $element = $(element);
var listOfSelectedItems = allBindingsAccessor().selectedOptions; var config = ko.toJS(valueAccessor());
var config = ko.utils.unwrapObservable(valueAccessor());
$element.multiselect(config);
$(element).multiselect(config);
if (allBindings.has('options')) {
if (isObservableArray(listOfSelectedItems)) { var options = allBindings.get('options');
if (ko.isObservable(options)) {
// Set the initial selection state on the multiselect list. ko.computed({
$(element).multiselect('select', ko.utils.unwrapObservable(listOfSelectedItems)); read: function() {
options();
// Subscribe to the selectedOptions: ko.observableArray setTimeout(function() {
listOfSelectedItems.subscribe(function (changes) { var ms = $element.data('multiselect');
var addedArray = [], deletedArray = []; if (ms)
forEach(changes, function (change) { ms.updateOriginalOptions();//Not sure how beneficial this is.
switch (change.status) { $element.multiselect('rebuild');
case 'added': }, 1);
addedArray.push(change.value); },
break; disposeWhenNodeIsRemoved: element
case 'deleted':
deletedArray.push(change.value);
break;
}
}); });
}
if (addedArray.length > 0) {
$(element).multiselect('select', addedArray);
}
if (deletedArray.length > 0) {
$(element).multiselect('deselect', deletedArray);
}
}, null, "arrayChange");
} }
},
update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var listOfItems = allBindingsAccessor().options, //value and selectedOptions are two-way, so these will be triggered even by our own actions.
ms = $(element).data('multiselect'), //It needs some way to tell if they are triggered because of us or because of outside change.
config = ko.utils.unwrapObservable(valueAccessor()); //It doesn't loop but it's a waste of processing.
if (allBindings.has('value')) {
if (isObservableArray(listOfItems)) { var value = allBindings.get('value');
// Subscribe to the options: ko.observableArray incase it changes later if (ko.isObservable(value)) {
listOfItems.subscribe(function (theArray) { ko.computed({
$(element).multiselect('rebuild'); read: function() {
}); value();
setTimeout(function() {
$element.multiselect('refresh');
}, 1);
},
disposeWhenNodeIsRemoved: element
}).extend({ rateLimit: 100, notifyWhenChangesStop: true });
}
} }
if (!ms) { //Switched from arrayChange subscription to general subscription using 'refresh'.
$(element).multiselect(config); //Not sure performance is any better using 'select' and 'deselect'.
} if (allBindings.has('selectedOptions')) {
else { var selectedOptions = allBindings.get('selectedOptions');
ms.updateOriginalOptions(); if (ko.isObservable(selectedOptions)) {
ko.computed({
read: function() {
selectedOptions();
setTimeout(function() {
$element.multiselect('refresh');
}, 1);
},
disposeWhenNodeIsRemoved: element
}).extend({ rateLimit: 100, notifyWhenChangesStop: true });
}
} }
ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
$element.multiselect('destroy');
});
},
update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
var $element = $(element);
var config = ko.toJS(valueAccessor());
$element.multiselect('setOptions', config);
$element.multiselect('rebuild');
} }
}; };
} }
function isObservableArray(obj) {
return ko.isObservable(obj) && !(obj.destroyAll === undefined);
}
function forEach(array, callback) { function forEach(array, callback) {
for (var index = 0; index < array.length; ++index) { for (var index = 0; index < array.length; ++index) {
callback(array[index]); callback(array[index]);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment