2018-05-31 09:52:39 +00:00
|
|
|
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
|
|
|
|
*/
|
2018-10-19 17:54:46 +00:00
|
|
|
export class Sortable {}
|
2018-05-31 09:52:39 +00:00
|
|
|
|
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 {
|
2018-05-31 09:52:39 +00:00
|
|
|
constructor() {
|
2018-10-18 07:24:20 +00:00
|
|
|
super();
|
2018-05-31 09:52:39 +00:00
|
|
|
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-06-07 21:47:19 +00:00
|
|
|
|
2018-10-18 07:24:20 +00:00
|
|
|
for (let i = 0; i < value.length; i++)
|
2018-10-19 17:54:46 +00:00
|
|
|
this.proxiedData[i] = this.createRow(Object.assign({}, value[i]), i, value[i]);
|
2018-06-07 21:47:19 +00:00
|
|
|
} else
|
2018-10-18 07:24:20 +00:00
|
|
|
this.proxiedData = null;
|
2018-05-31 09:52:39 +00:00
|
|
|
|
2018-10-18 07:24:20 +00:00
|
|
|
this.data = null;
|
2018-05-31 09:52:39 +00:00
|
|
|
this.resetChanges();
|
|
|
|
}
|
|
|
|
|
|
|
|
get data() {
|
|
|
|
return this._data;
|
|
|
|
}
|
|
|
|
|
2018-10-18 07:24:20 +00:00
|
|
|
set data(value) {
|
|
|
|
this._data = value;
|
|
|
|
this.emit('dataChange');
|
2018-05-31 09:52:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
remove(index) {
|
2018-10-18 07:24:20 +00:00
|
|
|
let [item] = this.data.splice(index, 1);
|
2018-05-31 09:52:39 +00:00
|
|
|
|
2018-10-18 07:24:20 +00:00
|
|
|
let proxiedIndex = this.proxiedData.indexOf(item);
|
|
|
|
this.proxiedData.splice(proxiedIndex, 1);
|
2018-05-31 09:52:39 +00:00
|
|
|
|
|
|
|
if (!item.$isNew)
|
|
|
|
this.removed.push(item);
|
2018-10-18 07:24:20 +00:00
|
|
|
|
|
|
|
this.isChanged = true;
|
|
|
|
this.emit('rowRemove', index);
|
2018-05-31 09:52:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
insert(data) {
|
|
|
|
data = Object.assign(data || {}, this.link);
|
2018-10-18 07:24:20 +00:00
|
|
|
let newRow = this.createRow(data, null);
|
2018-05-31 09:52:39 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2018-10-19 17:54:46 +00:00
|
|
|
createRow(obj, index, orgRow) {
|
2018-10-18 07:24:20 +00:00
|
|
|
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,
|
2018-10-19 17:54:46 +00:00
|
|
|
$orgRow: orgRow,
|
2018-10-18 07:24:20 +00:00
|
|
|
$oldData: null,
|
|
|
|
$isNew: false
|
|
|
|
});
|
|
|
|
return proxy;
|
2018-05-31 09:52:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
2018-10-19 17:54:46 +00:00
|
|
|
for (let row of data) {
|
2018-10-18 07:24:20 +00:00
|
|
|
if (row.$isNew) {
|
2018-10-19 17:54:46 +00:00
|
|
|
let orgRow = {};
|
2018-10-18 07:24:20 +00:00
|
|
|
for (let prop in row)
|
|
|
|
if (prop.charAt(0) !== '$')
|
2018-10-19 17:54:46 +00:00
|
|
|
orgRow[prop] = row[prop];
|
|
|
|
row.$orgIndex = orgData.push(orgRow) - 1;
|
|
|
|
row.$orgRow = orgRow;
|
2018-10-18 07:24:20 +00:00
|
|
|
row.$isNew = false;
|
|
|
|
} else if (row.$oldData)
|
|
|
|
for (let prop in row.$oldData)
|
2018-10-19 17:54:46 +00:00
|
|
|
row.$orgRow[prop] = row[prop];
|
2018-10-18 07:24:20 +00:00
|
|
|
}
|
2018-05-31 09:52:39 +00:00
|
|
|
|
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-05-31 09:52:39 +00:00
|
|
|
}
|
2018-10-18 07:24:20 +00:00
|
|
|
|
|
|
|
this.resetChanges();
|
2018-05-31 09:52:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
undoChanges() {
|
2018-10-18 07:24:20 +00:00
|
|
|
let data = this.proxiedData;
|
|
|
|
if (!data) return;
|
2018-05-31 09:52:39 +00:00
|
|
|
|
|
|
|
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);
|
2018-05-31 09:52:39 +00:00
|
|
|
if (row.$isNew)
|
|
|
|
data.splice(i--, 1);
|
|
|
|
}
|
|
|
|
|
2018-10-18 07:24:20 +00:00
|
|
|
let removed = this.removed;
|
2018-05-31 09:52:39 +00:00
|
|
|
|
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-06-07 21:47:19 +00:00
|
|
|
|
2018-10-18 07:24:20 +00:00
|
|
|
this.resetChanges();
|
2018-06-07 21:47:19 +00:00
|
|
|
}
|
2018-05-31 09:52:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ngModule.component('vnModelProxy', {
|
|
|
|
controller: ModelProxy,
|
|
|
|
bindings: {
|
|
|
|
orgData: '<?',
|
2018-10-18 07:24:20 +00:00
|
|
|
data: '=?'
|
2018-05-31 09:52:39 +00:00
|
|
|
}
|
|
|
|
});
|