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; } ,_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); 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); } } ,setAll: function (params) { this.assign (params); } ,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; default: if (type instanceof Object) return JSON.parse (value); else return value; } }