Skip to content

Instantly share code, notes, and snippets.

@loyalchow
Created October 8, 2011 16:59
Show Gist options
  • Save loyalchow/1272554 to your computer and use it in GitHub Desktop.
Save loyalchow/1272554 to your computer and use it in GitHub Desktop.
/*
dependencies:
- knockout-1.3.0.js
- simple-class.js
- amplify.js
*/
(function() {
window.__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
ko.Base = Class.extend({
init: function() {
this.requestLoading = ko.observable(0);
this.requestError = ko.observable();
},
serialize: function(obj) {
function preserialize(js) {
delete js.requestLoading;
delete js.requestError;
delete js.isSelected;
if (js.items) js = ko.toJS(js.items);
if (js instanceof Array) {
ko.utils.arrayForEach(js, function(obj) {
delete obj.requestLoading;
delete obj.requestError;
delete obj.isSelected;
for (var key in obj) {
if (obj[key] && obj[key]["items"]) {
obj[key] = preserialize(obj[key]);
}
}
});
}
return js;
}
if (typeof obj === 'undefined') obj = this;
var js = preserialize(ko.toJS(obj));
return ko.toJSON(js);
},
loadStore: function() {
this.loadJSON(amplify.store('_stored_' + this.className));
},
store: function() {
amplify.store('_stored_' + this.className, this.serialize());
},
request: function(id, data, callback) {
if (typeof data === 'function') {
callback = data;
data = JSON.parse(this.serialize());
}
if (!this.requestLoading()) {
appModel.requestLoading(appModel.requestLoading() + 1);
appModel.requestError(null);
if (this !== appModel) {
this.requestLoading(1);
this.requestError(null);
}
amplify.request({
resourceId: id,
data: data,
success: __bind(function(response) {
appModel.requestLoading(appModel.requestLoading() - 1);
if (this !== appModel) this.requestLoading(0);
callback(response);
}, this),
error: __bind(function(response) {
appModel.requestLoading(appModel.requestLoading() - 1);
appModel.requestError(response);
if (this !== appModel) {
this.requestLoading(0);
this.requestError(response);
}
}, this)
});
}
},
destroy: function() {
if (this.parent()) this.parent().remove(this);
}
});
ko.Item = ko.Base.extend({
isSelected: function() {
if (this.parent() && this.parent()._selected() === this) return true;
return false;
},
select: function() {
if (this.parent()) this.parent().selected(this);
},
deselect: function() {
if (this.isSelected()) this.parent().selected(null);
}
});
ko.MultipleSelectItem = ko.Base.extend({
init: function() {
this._super();
this.isSelected = ko.observable(false);
},
select: function() {
this.isSelected(true);
},
deselect: function() {
this.isSelected(false);
}
});
ko.List = ko.Base.extend({
init: function() {
this._super();
this.items = ko.observableArray([]);
this._selected = ko.observable();
this.selected = ko.dependentObservable({
read: function() {
return ko.utils.arrayFirst(this.items(), function(item) {
return item.isSelected();
});
},
write: function(value) {
this._selected(value);
},
owner: this
});
},
remove: function(items) {
if (!(items instanceof Array)) items = [items];
this.items.removeAll(items);
},
each: function(iterator) {
ko.utils.arrayForEach(this.items(), iterator);
},
filter: function(iterator) {
return ko.utils.arrayFilter(this.items(), iterator);
},
sortBy: function(attrName, isDesc) {
this.items.sort(function(a,b) {
if (isDesc) return a[attrName]() < b[attrName]();
return a[attrName]() > b[attrName]();
});
},
clear: function() {
this.items([]);
},
loadJSON: function(data) {
this.clear();
this.addJSON(data);
},
selectIndex: function(index) {
this.items()[index].select();
},
clearSelected: function() {
ko.utils.arrayForEach(this.items(), function(item) {
item.deselect();
});
}
});
ko.MultipleSelectList = ko.List.extend({
init: function() {
this._super();
this.selected = ko.dependentObservable(function() {
return ko.utils.arrayFilter(this.items(), function(item) {
return item.isSelected();
});
}, this);
}
});
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment