UNPKG

lazo-next

Version:

A client-server web framework built on Node.js that allows front-end developers to easily create a 100% SEO compliant, component MVC structured web application with an optimized first page load.

237 lines (198 loc) 10.4 kB
define(['lazoModel', 'utils/modelLoader', 'utils/module', 'async', 'underscore', 'utils/dataschema-json'], function (LazoModel, modelLoader, module, async, _, SchemaJSON) { 'use strict'; var UtilModel = { process: function (modelName, options, type, child) { var modelInstances = options.ctx._rootCtx.modelInstances, modelList = options.ctx._rootCtx.modelList, gid = LazoModel._getGlobalId(modelName, options.params), path = 'models/' + modelName + '/' + type; function checkProcessing() { if (modelInstances[gid] === null) { return; } else if (modelInstances[gid].processing) { setTimeout(checkProcessing, 0); } else if (options.success) { _.defer(options.success, modelInstances[gid]); } } options.error = options.error || function (err) { throw err; }; // user did not define error bubble up 500 if (modelInstances[gid]) { checkProcessing(); return; } modelInstances[gid] = {}; modelInstances[gid].processing = true; var _fetch = function (Model, _default) { var data = child ? child.data : (modelList[gid] && modelList[gid].data ? modelList[gid].data : null); var m = new Model(data, {name: modelName, ctx: options.ctx, params: options.params, parse: data !== null}); var registerModel = function (m, options, gid) { // add model meta info to modelList var modelMeta = { data: m._resp, cid: m.cid, id: m.id, name: m.name, params: options.params }; if (type === 'collection') { modelMeta.idMap = []; m.each(function (model) { modelMeta.idMap.push({cid: model.cid, id: model.id}); }); } m.ctx._rootCtx.modelList[gid] = modelMeta; m.ctx._rootCtx.modelInstances[gid] = m; if (m.modelsSchema) { var tasks = [], success = options.success; _.each(m.modelsSchema, function (modelSchemaDef) { var submodeldata = SchemaJSON.apply({resultListLocator: modelSchemaDef.locator}, modelMeta.data), subtype = submodeldata && submodeldata.results ? (_.isArray(submodeldata.results) ? 'collection' : 'model') : 'model'; tasks.push(function (cb) { options.success = function () {cb();}; UtilModel.process(modelSchemaDef.name, options, subtype, { parentModel: m, data: submodeldata.results, schema: modelSchemaDef }); }); }); async.parallel(tasks, function (err, results) { if (success) { return success(m); } }); } else { if (options.success) { return options.success(m); } } }; m._default = _default; if (options.params && type === 'model') { m.id = _.result(options.params, m.idAttribute); } if (!_default) { module.addPath(path, options.ctx); } if (child && child.parentModel) { m.lazoParent = child.parentModel; child.parentModel.lazoChildren = child.parentModel.lazoChildren || {}; child.parentModel.lazoChildren[modelName] = m; if (child.schema && child.schema.prop) { child.parentModel[child.schema.prop] = m; child.parentModel._childNames = child.parentModel._childNames || []; child.parentModel._childNames.push(child.schema.prop); } } // if data in list don't make tunnel call if (modelList[gid]) { m.cid = modelList[gid].cid; m._default = _default; if (modelList[gid].idMap) { _.each(modelList[gid].idMap, function (elem) { var modelItem = m.get(elem.id); if (modelItem) { modelItem.cid = elem.cid; } }); } modelInstances[gid] = m; if (options.success) { options.success(m); } return; } else if (options.fetch === false || child) { if (child && child.data) { m._resp = child.data; } registerModel(m, options, gid); } else { m.fetch({ success: function (m) { registerModel(m, options, gid); }, error: function (model, response, opts) { modelInstances[gid] = null; LAZO.logger.debug('[common.utils.model.process] Error loading model %s', modelName); if (options.error) { // TODO: error handling return options.error(model, response, opts); } } }); } }; modelLoader(modelName, type, _fetch); }, create: function (name, attributes, options, type) { var _create = function (Model, _default) { var modelInstances = options.ctx._rootCtx.modelInstances, gid = LazoModel._getGlobalId(name, options.params); if (modelInstances[gid]) { options.success(modelInstances[gid]); return; } var m = new Model((type === 'model' ? attributes : null), {name: name, ctx: options.ctx, params: options.params, parse: true}); m._default = _default; var modelMeta = { data: (type === 'model' ? attributes : null), cid: m.cid, id: m.id, name: m.name, params: options.params }; m.ctx._rootCtx.modelList[gid] = modelMeta; m.ctx._rootCtx.modelInstances[gid] = m; if (type === 'model') { if (options.persist == false) { options.success(m); } else { m.save({}, { success: function (model) { if (options.success) { options.success(model); } }, error: function (model, xhr, opts) { LAZO.logger.warn('[common.utils.model.createModel] Error creating model %s', name); if (options.error) { return options.error(model, xhr, opts); } } }); } } else { if (!_.isArray(attributes)) { if (options.error) { options.error(m, 'attributes must be an array', options); } return; } var modelOptions = {}; if (options && options.persist) { modelOptions.persist = options.persist; } _.each(attributes, function (modelData) { m.create(modelData, modelOptions); }); if (options.success) { options.success(m); } } }; modelLoader(name, type, _create); } }; return UtilModel; });