Add Base model type
Mostly copied from gitlab.com/schwalbe-hd/schwalbe It allows both the names `id` and `uuid` for the identifier field of an instance
This commit is contained in:
parent
a5c50bd8f9
commit
625a6d72f7
64
karaokatalog/ui/static/model/Base.js
Normal file
64
karaokatalog/ui/static/model/Base.js
Normal file
@ -0,0 +1,64 @@
|
||||
function toMap(objs) {
|
||||
return new Map(objs.map(obj => [obj.id || obj.uuid, obj]))
|
||||
}
|
||||
|
||||
export class Base {
|
||||
/**
|
||||
* A Map mapping ids to instances of `Base`.
|
||||
* Must be treated as private.
|
||||
*/
|
||||
static _byId = null
|
||||
|
||||
/**
|
||||
* @return A list of all instances of `Base`
|
||||
*/
|
||||
static get all() {
|
||||
return this._byId ? Array.from(this._byId.values()) : null
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {str} id A id
|
||||
* @returns The instance with the given id, if it exists
|
||||
*/
|
||||
static get(id) {
|
||||
return this._byId ? this._byId.get(id) : null
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the objects from the API, unless the objects have already been loaded.
|
||||
* They are then stored in `this.byUid`.
|
||||
*
|
||||
* @returns Nothing.
|
||||
*/
|
||||
static async load() {
|
||||
if (!this._byId) {
|
||||
const objects = await this.forceLoad()
|
||||
// Hack: We get plain JSON objects from the server, however, we'd like
|
||||
// them to actually be instances of the classes we define. So, we first create a new empty
|
||||
// instance of whatever subclass of `Base` we are currently in using `new this()`,
|
||||
// and then copy all properties from the plain object over to the instance
|
||||
// using `Object.assign`.
|
||||
const instances = objects.map(obj => Object.assign(new this(), obj))
|
||||
this._byId = toMap(instances)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the objects were already loaded, forget them and load them again.
|
||||
* If the objects were not yet loaded, don't do anything.
|
||||
*/
|
||||
static refresh() {
|
||||
if (this._byId) {
|
||||
this._byId = null
|
||||
this.load()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the objects from the API and return them.
|
||||
* Abstract method, must be overriden in child classes.
|
||||
*
|
||||
* @returns A list of instances.
|
||||
*/
|
||||
static async forceLoad() {}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user