snappymail/dev/Knoin/AbstractModel.js

122 lines
2.8 KiB
JavaScript
Raw Normal View History

function disposeOne(disposable) {
if (disposable && 'function' === typeof disposable.dispose) {
disposable.dispose();
}
}
2016-07-07 05:03:30 +08:00
2020-10-25 18:46:58 +08:00
function typeCast(curValue, newValue) {
switch (typeof curValue)
{
2020-10-25 18:46:58 +08:00
case 'boolean': return !!newValue;
case 'number': return isFinite(newValue) ? parseFloat(newValue) : 0;
case 'string': return null != newValue ? '' + newValue : '';
2020-10-23 21:15:54 +08:00
case 'object':
2020-10-25 18:46:58 +08:00
if (curValue.constructor.reviveFromJson) {
return curValue.constructor.reviveFromJson(newValue) || undefined;
2020-10-23 21:15:54 +08:00
}
2020-10-25 18:46:58 +08:00
if (!Array.isArray(curValue) || !Array.isArray(newValue))
2020-10-23 21:15:54 +08:00
return undefined;
}
2020-10-25 18:46:58 +08:00
return newValue;
}
2019-07-05 03:19:24 +08:00
export class AbstractModel {
2016-09-10 06:38:16 +08:00
disposables = [];
2020-10-19 01:19:45 +08:00
constructor() {
/*
if (new.target === AbstractModel) {
2020-10-23 21:15:54 +08:00
throw new Error("Can't instantiate AbstractModel!");
}
*/
2016-07-07 05:03:30 +08:00
}
2020-10-25 18:46:58 +08:00
addObservables(obj) {
Object.entries(obj).forEach(([key, value]) => this[key] = ko.observable(value) );
/*
Object.entries(obj).forEach(([key, value]) =>
this[key] = Array.isArray(value) ? ko.observableArray(value) : ko.observable(value)
);
*/
}
addSubscribables(obj) {
Object.entries(obj).forEach(([key, fn]) => this.disposables.push( this[key].subscribe(fn) ) );
2016-07-07 05:03:30 +08:00
}
2019-07-05 03:19:24 +08:00
onDestroy() {
2020-10-25 18:46:58 +08:00
this.disposables.forEach(disposeOne);
Object.entries(this).forEach(([key, value]) => {
disposeOne(value);
this[key] = null;
});
2016-07-07 05:03:30 +08:00
}
/**
* @static
* @param {FetchJson} json
* @returns {boolean}
*/
static validJson(json) {
return !!(json && ('Object/'+this.name.replace('Model', '') === json['@Object']));
}
/**
* @static
* @param {FetchJson} json
* @returns {*Model}
*/
static reviveFromJson(json) {
let obj = this.validJson(json) ? new this() : null;
2020-10-23 21:15:54 +08:00
obj && obj.revivePropertiesFromJson(json);
return obj;
}
revivePropertiesFromJson(json) {
let model = this.constructor;
try {
2020-10-23 21:15:54 +08:00
if (!model.validJson(json)) {
return false;
}
Object.entries(json).forEach(([key, value]) => {
if ('@' !== key[0]) {
key = key[0].toLowerCase() + key.substr(1);
2020-10-23 21:15:54 +08:00
switch (typeof this[key])
{
case 'function':
2020-10-23 21:15:54 +08:00
if (ko.isObservable(this[key])) {
value = typeCast(this[key](), value);
if (undefined !== value) {
this[key](value);
break;
}
// console.log((typeof this[key]())+' '+(model.name)+'.'+key+' not revived');
}
2020-10-23 21:15:54 +08:00
// else console.log(model.name + '.' + key + ' is a function');
break;
case 'boolean':
case 'number':
2020-10-23 21:15:54 +08:00
case 'object':
case 'string':
value = typeCast(this[key], value);
if (undefined !== value) {
this[key] = value;
break;
}
// fall through
case 'undefined':
default:
// console.log((typeof this[key])+' '+(model.name)+'.'+key+' not revived');
}
}
});
} catch (e) {
2020-10-23 21:15:54 +08:00
console.log(model.name);
console.error(e);
}
2020-10-23 21:15:54 +08:00
return true;
}
2016-07-07 05:03:30 +08:00
}