123 lines
2.3 KiB
JavaScript
123 lines
2.3 KiB
JavaScript
|
|
var Lot = require('./lot');
|
|
var LotIface = require('./lot-iface');
|
|
var Spec = require('./spec');
|
|
var Value = require('./value');
|
|
|
|
module.exports = new Class({
|
|
Extends: Lot
|
|
,Tag: 'vn-lot-query'
|
|
,Properties: {
|
|
fields: {
|
|
type: Array
|
|
,set: function(x) {
|
|
this._fields = x;
|
|
this._onSourceChange();
|
|
}
|
|
,get: function() {
|
|
return this._fields;
|
|
}
|
|
},
|
|
source: {
|
|
type: LotIface
|
|
,set: function(x) {
|
|
this.link({_source: x}, {change: this._onSourceChange});
|
|
this._onSourceChange();
|
|
}
|
|
,get: function() {
|
|
return this._source;
|
|
}
|
|
}
|
|
}
|
|
|
|
,initialize: function(props) {
|
|
Object.assign(this, {
|
|
_fields: null,
|
|
_source: null,
|
|
_lockSource: false,
|
|
_specs: {}
|
|
});
|
|
this.parent(props);
|
|
}
|
|
|
|
,appendChild: function(child) {
|
|
if (!(child instanceof Spec))
|
|
throw new Error('VnLotQuery: Child must be a Vn.Spec instance');
|
|
|
|
this._specs[child.name] = child;
|
|
this._onSourceChange();
|
|
}
|
|
|
|
,_onSourceChange: function() {
|
|
if (this._lockSource)
|
|
return;
|
|
|
|
var params = this._source ? this._source.params : {};
|
|
var myParams = {};
|
|
|
|
for (var key in this._specs)
|
|
myParams[key] = Value.simpleClone(params[key]);
|
|
|
|
this.assign(myParams);
|
|
}
|
|
|
|
,assign: function(params) {
|
|
params = this.transformParams(params);
|
|
var diff = Value.partialDiff(this._params, params);
|
|
this._assign(diff);
|
|
}
|
|
|
|
,setAll: function(params) {
|
|
params = this.transformParams(params);
|
|
var diff = Value.diff(this._params, params);
|
|
this._assign(diff);
|
|
}
|
|
|
|
,_assign: function(diff) {
|
|
if (diff) {
|
|
Object.assign(this._params, diff);
|
|
|
|
if (this.source) {
|
|
this._lockSource = true;
|
|
this.source.assign(diff);
|
|
this._lockSource = false;
|
|
}
|
|
|
|
this._paramsChanged(diff);
|
|
this.changed(diff);
|
|
}
|
|
}
|
|
|
|
,transformParams: function(params) {
|
|
var newParams = {};
|
|
|
|
for (var key in this._specs) {
|
|
var spec = this._specs[key];
|
|
if (params[key])
|
|
newParams[key] = cast(params[key], spec.type);
|
|
}
|
|
|
|
return Object.assign(params, newParams);
|
|
}
|
|
});
|
|
|
|
function cast(value, type) {
|
|
switch (type) {
|
|
case Boolean:
|
|
return (/^(true|1)$/i).test(value);
|
|
case Number:
|
|
return 0 + new Number(value);
|
|
case Date:
|
|
var date = new Date(value);
|
|
date.setHours(0, 0, 0, 0);
|
|
return date;
|
|
case String:
|
|
return value;
|
|
default:
|
|
if (type instanceof Object)
|
|
return JSON.parse(value);
|
|
else
|
|
return value;
|
|
}
|
|
}
|