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) { //value and selectedOptions are two-way, so these will be triggered even by our own actions.
$(element).multiselect('deselect', deletedArray); //It needs some way to tell if they are triggered because of us or because of outside change.
//It doesn't loop but it's a waste of processing.
if (allBindings.has('value')) {
var value = allBindings.get('value');
if (ko.isObservable(value)) {
ko.computed({
read: function() {
value();
setTimeout(function() {
$element.multiselect('refresh');
}, 1);
},
disposeWhenNodeIsRemoved: element
}).extend({ rateLimit: 100, notifyWhenChangesStop: true });
}
}
//Switched from arrayChange subscription to general subscription using 'refresh'.
//Not sure performance is any better using 'select' and 'deselect'.
if (allBindings.has('selectedOptions')) {
var selectedOptions = allBindings.get('selectedOptions');
if (ko.isObservable(selectedOptions)) {
ko.computed({
read: function() {
selectedOptions();
setTimeout(function() {
$element.multiselect('refresh');
}, 1);
},
disposeWhenNodeIsRemoved: element
}).extend({ rateLimit: 100, notifyWhenChangesStop: true });
} }
}, null, "arrayChange");
} }
},
update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var listOfItems = allBindingsAccessor().options,
ms = $(element).data('multiselect'),
config = ko.utils.unwrapObservable(valueAccessor());
if (isObservableArray(listOfItems)) { ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
// Subscribe to the options: ko.observableArray incase it changes later $element.multiselect('destroy');
listOfItems.subscribe(function (theArray) {
$(element).multiselect('rebuild');
}); });
} },
if (!ms) { update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
$(element).multiselect(config); var $element = $(element);
} var config = ko.toJS(valueAccessor());
else {
ms.updateOriginalOptions(); $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