salix/client/core/src/components/model-proxy/model-proxy.js

216 lines
4.9 KiB
JavaScript
Raw Normal View History

import ngModule from '../../module';
2018-10-18 07:24:20 +00:00
import EventEmitter from '../../lib/event-emitter';
/**
* A filtrable model.
*
* @property {Function} filter The filter function
*/
export class Filtrable {
applyFilter(userFilter, userParams) {}
addFilter(userFilter, userParams) {}
removeFilter() {}
}
/**
* A sortable model.
*
* @property {String|Array<String>|Function} order The sort specification
*/
export class Sortable {
}
2018-10-18 07:24:20 +00:00
/**
* Paginable model.
*
* @property {Number} limit The page size
*/
export class Paginable {
get isLoading() {}
get moreRows() {}
loadMore() {}
}
/**
* A data model.
*
* @event dataChange Emitted when data property changes
*/
export class DataModel extends EventEmitter {
get data() {}
refresh() {}
clear() {}
}
ngModule.component('vnDataModel', {
controller: DataModel,
bindings: {
data: '=?',
autoLoad: '<?',
autoSync: '<?',
order: '@?',
limit: '<?'
}
});
/**
* A data model that monitorizes changes to the data.
*
* @event dataChange Emitted when data property changes
*/
export default class ModelProxy extends DataModel {
constructor() {
2018-10-18 07:24:20 +00:00
super();
this.resetChanges();
}
get orgData() {
return this._orgData;
}
set orgData(value) {
this._orgData = value;
2018-10-18 07:24:20 +00:00
if (value) {
this.proxiedData = new Array(value.length);
2018-10-18 07:24:20 +00:00
for (let i = 0; i < value.length; i++)
this.proxiedData[i] = this.createRow(Object.assign({}, value[i]), i);
} else
2018-10-18 07:24:20 +00:00
this.proxiedData = null;
2018-10-18 07:24:20 +00:00
this.data = null;
this.resetChanges();
}
get data() {
return this._data;
}
2018-10-18 07:24:20 +00:00
set data(value) {
this._data = value;
this.emit('dataChange');
}
remove(index) {
2018-10-18 07:24:20 +00:00
let [item] = this.data.splice(index, 1);
2018-10-18 07:24:20 +00:00
let proxiedIndex = this.proxiedData.indexOf(item);
this.proxiedData.splice(proxiedIndex, 1);
if (!item.$isNew)
this.removed.push(item);
2018-10-18 07:24:20 +00:00
this.isChanged = true;
this.emit('rowRemove', index);
}
insert(data) {
data = Object.assign(data || {}, this.link);
2018-10-18 07:24:20 +00:00
let newRow = this.createRow(data, null);
newRow.$isNew = true;
2018-10-18 07:24:20 +00:00
let index = this.proxiedData.push(newRow) - 1;
if (this.data)
this.data.push(newRow);
this.isChanged = true;
this.emit('rowInsert', index);
return index;
}
createRow(obj, index) {
let proxy = new Proxy(obj, {
set: (obj, prop, value) => {
if (prop.charAt(0) !== '$' && value !== obj[prop] && !obj.$isNew) {
if (!obj.$oldData)
obj.$oldData = {};
if (!obj.$oldData[prop])
obj.$oldData[prop] = value;
this.isChanged = true;
}
return Reflect.set(obj, prop, value);
}
});
Object.assign(proxy, {
$orgIndex: index,
$oldData: null,
$isNew: false
});
return proxy;
}
resetChanges() {
this.removed = [];
2018-10-18 07:24:20 +00:00
this.isChanged = false;
let data = this.proxiedData;
if (data)
for (let row of data)
row.$oldData = null;
}
applyChanges() {
let data = this.proxiedData;
let orgData = this.orgData;
if (!data) return;
for (let row of this.removed) {
if (row.$isNew) {
let data = {};
for (let prop in row)
if (prop.charAt(0) !== '$')
data[prop] = row[prop];
row.$orgIndex = orgData.push(data) - 1;
row.$isNew = false;
} else if (row.$oldData)
for (let prop in row.$oldData)
orgData[row.$orgIndex][prop] = row[prop];
}
2018-10-18 07:24:20 +00:00
let removed = this.removed;
if (removed) {
removed = removed.sort((a, b) => b.$orgIndex - a.$orgIndex);
for (let row of this.removed)
orgData.splice(row.$orgIndex, 1);
}
2018-10-18 07:24:20 +00:00
this.resetChanges();
}
undoChanges() {
2018-10-18 07:24:20 +00:00
let data = this.proxiedData;
if (!data) return;
for (let i = 0; i < data.length; i++) {
let row = data[i];
if (row.$oldData)
2018-10-18 07:24:20 +00:00
Object.assign(row, row.$oldData);
if (row.$isNew)
data.splice(i--, 1);
}
2018-10-18 07:24:20 +00:00
let removed = this.removed;
2018-10-18 07:24:20 +00:00
if (removed) {
removed = removed.sort((a, b) => a.$orgIndex - b.$orgIndex);
for (let row of this.removed)
data.splice(row.$orgIndex, 0, row);
}
2018-10-18 07:24:20 +00:00
this.resetChanges();
}
}
ngModule.component('vnModelProxy', {
controller: ModelProxy,
bindings: {
orgData: '<?',
2018-10-18 07:24:20 +00:00
data: '=?'
}
});