229 lines
5.2 KiB
JavaScript
229 lines
5.2 KiB
JavaScript
import ngModule from '../../module';
|
|
import ModelProxy from '../model-proxy/model-proxy';
|
|
|
|
/**
|
|
* Model that uses an array as datasource.
|
|
*/
|
|
export default class ArrayModel extends ModelProxy {
|
|
constructor($q, $filter, $element, $scope) {
|
|
super($element, $scope);
|
|
this.$q = $q;
|
|
this.$filter = $filter;
|
|
this.autoLoad = true;
|
|
this.limit = 0;
|
|
this.userFilter = [];
|
|
|
|
this.clear();
|
|
}
|
|
|
|
$onInit() {
|
|
this.autoRefresh();
|
|
}
|
|
|
|
get isLoading() {
|
|
return false;
|
|
}
|
|
|
|
autoRefresh() {
|
|
if (this.autoLoad)
|
|
return this.refresh();
|
|
return this.$q.resolve();
|
|
}
|
|
|
|
refresh() {
|
|
this.data = this.proccessData(0);
|
|
return this.$q.resolve();
|
|
}
|
|
|
|
proccessData(skip) {
|
|
if (!this.proxiedData) return null;
|
|
let data = this.proxiedData.slice();
|
|
|
|
let filter = {
|
|
order: this.order,
|
|
limit: this.limit
|
|
};
|
|
|
|
if (this.where)
|
|
filter.where = [this.where];
|
|
|
|
filter = this.mergeFilters(this.userFilter, filter);
|
|
|
|
let where = filter.where;
|
|
|
|
if (where) {
|
|
if (!Array.isArray(where))
|
|
where = [where];
|
|
|
|
for (let subWhere of where)
|
|
data = this.$filter('filter')(data, subWhere);
|
|
}
|
|
|
|
let order = filter.order;
|
|
|
|
if (typeof order === 'string')
|
|
order = order.split(/\s*,\s*/);
|
|
|
|
if (Array.isArray(order)) {
|
|
let orderComp = [];
|
|
|
|
for (let field of order) {
|
|
let split = field.split(/\s+/);
|
|
orderComp.push({
|
|
field: split[0],
|
|
way: split[1] === 'DESC' ? -1 : 1
|
|
});
|
|
}
|
|
|
|
data = data.sort((a, b) => this.sortFunc(a, b, orderComp));
|
|
} else if (typeof order === 'function')
|
|
data = data.sort(order);
|
|
|
|
this.skip = skip;
|
|
|
|
if (filter.limit) {
|
|
let end = skip + filter.limit;
|
|
this.moreRows = end < data.length;
|
|
data = data.slice(this.skip, end);
|
|
} else
|
|
this.moreRows = false;
|
|
|
|
this.currentFilter = filter;
|
|
return data;
|
|
}
|
|
|
|
applyFilter(user, params) {
|
|
this.userFilter = user;
|
|
this.userParams = params;
|
|
return this.refresh();
|
|
}
|
|
|
|
addFilter(user, params) {
|
|
this.userFilter = this.mergeFilters(user, this.userFilter);
|
|
this.userParams = Object.assign({}, this.userParams, params);
|
|
return this.refresh();
|
|
}
|
|
|
|
removeFilter() {
|
|
return applyFilter(null, null);
|
|
}
|
|
|
|
loadMore() {
|
|
if (!this.moreRows)
|
|
return this.$q.resolve();
|
|
|
|
let data = this.proccessData(this.skip + this.currentFilter.limit);
|
|
this.data = this.data.concat(data);
|
|
return this.$q.resolve();
|
|
}
|
|
|
|
clear() {
|
|
this.data = null;
|
|
this.userFilter = null;
|
|
this.moreRows = false;
|
|
this.skip = 0;
|
|
}
|
|
|
|
/**
|
|
* Saves current changes on the server.
|
|
*
|
|
* @return {Promise} The save request promise
|
|
*/
|
|
save() {
|
|
if (this.getChanges())
|
|
this.orgData = this.data;
|
|
|
|
super.save();
|
|
|
|
return this.$q.resolve();
|
|
}
|
|
|
|
sortFunc(a, b, order) {
|
|
for (let i of order) {
|
|
let compRes = this.compareFunc(a[i.field], b[i.field]) * i.way;
|
|
if (compRes !== 0)
|
|
return compRes;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
compareFunc(a, b) {
|
|
if (a === b)
|
|
return 0;
|
|
|
|
let aType = typeof a;
|
|
|
|
if (aType === typeof b) {
|
|
switch (aType) {
|
|
case 'string':
|
|
return a.localeCompare(b);
|
|
case 'number':
|
|
return a - b;
|
|
case 'boolean':
|
|
return a ? 1 : -1;
|
|
case 'object':
|
|
if (a instanceof Date && b instanceof Date)
|
|
return a.getTime() - b.getTime();
|
|
}
|
|
}
|
|
|
|
if (a === undefined)
|
|
return -1;
|
|
if (b === undefined)
|
|
return 1;
|
|
if (a === null)
|
|
return -1;
|
|
if (b === null)
|
|
return 1;
|
|
|
|
return a > b ? 1 : -1;
|
|
}
|
|
|
|
mergeFilters(src, dst) {
|
|
let mergedWhere = [];
|
|
let wheres = [dst.where, src.where];
|
|
|
|
for (let where of wheres) {
|
|
if (Array.isArray(where))
|
|
mergedWhere = mergedWhere.concat(where);
|
|
else if (where)
|
|
mergedWhere.push(where);
|
|
}
|
|
|
|
switch (mergedWhere.length) {
|
|
case 0:
|
|
mergedWhere = undefined;
|
|
break;
|
|
case 1:
|
|
mergedWhere = mergedWhere[0];
|
|
break;
|
|
}
|
|
|
|
return {
|
|
where: mergedWhere,
|
|
order: src.order || dst.order,
|
|
limit: src.limit || dst.limit
|
|
};
|
|
}
|
|
|
|
undoChanges() {
|
|
super.undoChanges();
|
|
this.refresh();
|
|
}
|
|
}
|
|
ArrayModel.$inject = ['$q', '$filter', '$element', '$scope'];
|
|
|
|
ngModule.vnComponent('vnArrayModel', {
|
|
controller: ArrayModel,
|
|
bindings: {
|
|
orgData: '<?',
|
|
data: '=?',
|
|
link: '<?',
|
|
order: '@?',
|
|
limit: '<?',
|
|
autoLoad: '<?',
|
|
autoSave: '<?'
|
|
}
|
|
});
|