Skip to content

Commit

Permalink
[DEV] Take care of namespace and child model descriptions in `desolat…
Browse files Browse the repository at this point in the history
…e()` too.

It is now possible to populate/desolate between the given JSON origin and the "rich model" in either way, respecting the modelDescription including `__namespace`, `__children` and `__serializable` properties.
  • Loading branch information
herom committed May 9, 2014
1 parent b689d4c commit 6b27de3
Show file tree
Hide file tree
Showing 2 changed files with 910 additions and 555 deletions.
122 changes: 110 additions & 12 deletions molder/molder.js
Original file line number Diff line number Diff line change
Expand Up @@ -148,29 +148,127 @@ var Molder = {
* @returns {Object} The plain desolated/reduced model.
*/
desolate: function (modelDescription, model) {
var serializableProperties = [],
desolatedModel = {};
var namespace = modelDescription.__namespace,
serializableProperties = [],
desolatedModel = null,
childModels = null;

if ('serializable' in modelDescription) {
serializableProperties = modelDescription.serializable;
if ('__serializable' in modelDescription) {
serializableProperties = modelDescription.__serializable;
} else {
serializableProperties = Object.keys(modelDescription);

var serializedClone = serializableProperties.slice();

serializedClone.every(function (clone, index) {
if (clone.match(/^__/)) {
serializableProperties.splice(index, 1);
}
});
}

// ignore the namespace property as it's only useful on populating from the origin
if (serializableProperties.indexOf('namespace') > -1) {
serializableProperties.splice(serializableProperties.indexOf('namespace'), 1);
if ('__children' in modelDescription) {
var childKeys = Object.keys(modelDescription.__children);
childModels = {};

childKeys.forEach(function (childKey) {
if (serializableProperties.indexOf(childKey) > -1) {
serializableProperties.splice(serializableProperties.indexOf(childKey), 1);
childModels[childKey] = this.desolate(modelDescription.__children[childKey], model[childKey]);
}
}.bind(this));
}

serializableProperties.forEach(function (key) {
var property = model[key];
desolatedModel = this._serialize(modelDescription, model, serializableProperties);

if (typeof property !== 'function') {
desolatedModel[key] = property;
if (desolatedModel && childModels) {
for (var childModel in childModels) {
if (childModels.hasOwnProperty(childModel)) {
desolatedModel[modelDescription[childModel]] = childModels[childModel];
}
}
});
}

if (namespace) {
desolatedModel = this._generateNamespacedContainer(namespace, desolatedModel);
}

return desolatedModel;
},

/**
* Serializes the model according to the modelDescription and the serializable properties given.
*
* @method _serialize
* @param {Object} modelDescription The description for this model.
* @param {Object|Array} model The model.
* @param {Array} serializableProperties The array of serializable model properties.
* @returns {Object|Array}
* @private
*/
_serialize: function (modelDescription, model, serializableProperties) {
var serialized;

if (Array.isArray(model) && model.length > 0) {
var serializedObject = {};
serialized = [];
model.forEach(function (obj) {
serializedObject = {};

for (var prop in obj) {
if (obj.hasOwnProperty(prop) && serializableProperties.indexOf(prop) > -1) {
serializedObject[modelDescription[prop]] = obj[prop];
}
}

serialized.push(serializedObject);
});
} else {
var propertyIndex = -1;
serialized = {};

for (var prop in model) {
propertyIndex = serializableProperties.indexOf(prop);

if (propertyIndex > -1 && model.hasOwnProperty(prop)) {
serialized[modelDescription[prop]] = model[prop];
serializableProperties.splice(propertyIndex, 1);
}
}
}

return serialized;
},

/**
* Returns a nested ("namespaced") Object/Container and places the optional given
* values object at the deepest object level.
*
* @method _generateNamespacedContainer
* @param {String} namespace The dot-separated (e.g.: "my.namespace") namespace string.
* @param {Object} values (optional) The values object at the end of the namespace.
* @returns {Object}
* @private
*/
_generateNamespacedContainer: function (namespace, values) {
var namespacedContainer = {};

if (values && typeof values === 'object') {
namespacedContainer = values;
}

if (typeof namespace === 'string') {
var parts = namespace.split('.'),
tmpObj;

for (var i = parts.length - 1; i >= 0; i--) {
tmpObj = {};
tmpObj[parts[i]] = namespacedContainer;
namespacedContainer = tmpObj;
}

return namespacedContainer;
}
}
};

Expand Down
Loading

0 comments on commit 6b27de3

Please sign in to comment.