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(x) { this._fields = x; this._onSourceChange(); } ,get() { return this._fields; } }, source: { type: LotIface ,set(x) { this.link({_source: x}, {change: this._onSourceChange}); this._onSourceChange(); } ,get() { return this._source; } } } ,initialize(props) { Object.assign(this, { _fields: null, _source: null, _lockSource: false, _specs: {} }); Lot.prototype.initialize.call(this, props); } ,appendChild(child) { if (!(child instanceof Spec)) throw new Error('VnLotQuery: Child must be a Vn.Spec instance'); this._specs[child.name] = child; this._onSourceChange(); } ,_onSourceChange() { 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(params) { params = this.transformParams(params); var diff = Value.partialDiff(this._params, params); this._assign(diff); } ,setAll(params) { params = this.transformParams(params); var diff = Value.diff(this._params, params); this._assign(diff); } ,_assign(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(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; } }