Created
January 21, 2016 11:16
-
-
Save mosson/07bb8c311cc42d2a695f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
import _ from 'lodash'; | |
import is from 'is_js'; | |
import { parseIntOrNull } from 'services/NumberUtils'; | |
class BaseModel { | |
static hasMany(name, targetClass, defaultID) { | |
/* eslint complexity: [0, 6] */ | |
if (!this.prototype[`_get_${name}`]) { | |
this.prototype[`_get_${name}`] = function (v) { | |
return this[name]; | |
}; | |
} | |
if (!this.prototype[`_update_${name}`]) { | |
this.prototype[`_update_${name}`] = function (v) { | |
if (!this.state[name]) this.state[name] = {}; | |
_.each(v, (props) => { | |
let id = props && props.id; | |
if (!id) return; | |
if (this.state[name][id]) { | |
this.state[name][id].update(props); | |
} else { | |
this.state[name][id] = new targetClass(props); | |
} | |
this.state[name][id]._updatedAt = new Date().getTime(); | |
}); | |
}; | |
} | |
if (!this.prototype[`_destroy_${name}`]) { | |
this.prototype[`_destroy_${name}`] = function (v) { | |
if (!this.state[name]) return []; | |
_.each(v || [], (props) => { | |
let id = props && props.id; | |
if (!id) return; | |
if (this.state[name][id]) { | |
this.state[name][id].destroy(props); | |
if (props._destroyed) delete this.state[name][id]; | |
} | |
}); | |
}; | |
} | |
if (!this.prototype[`_${name}_as_json`]) { | |
this.prototype[`_${name}_as_json`] = function () { | |
if (!this.state[name]) return []; | |
return _.map(this.state[name], (model) => { | |
return model.asJSON(); | |
}); | |
}; | |
} | |
if (!(name in this.prototype)) { | |
Object.defineProperty(this.prototype, name, { | |
key : name, | |
enumerable : false, | |
configurable: true, | |
get : function () { | |
return _.values(this.state[name]); | |
} | |
}); | |
} | |
} | |
static hasOne(name, targetClass, defaultID) { | |
if (!this.prototype[`_get_${name}`]) { | |
this.prototype[`_get_${name}`] = function (v) { | |
return this[name]; | |
}; | |
} | |
if (!this.prototype[`_update_${name}`]) { | |
this.prototype[`_update_${name}`] = function (v) { | |
if (this.state[name]) { | |
this.state[name].update(v); | |
} else { | |
this.state[name] = new targetClass(v); | |
} | |
this.state[name]._updatedAt = new Date().getTime(); | |
}; | |
} | |
if (!this.prototype[`_destroy_${name}`]) { | |
this.prototype[`_destroy_${name}`] = function (v) { | |
if (this.state[name]) { | |
this.state[name].destroy(v); | |
if (v._destroyed) delete this.state[name]; | |
} | |
}; | |
} | |
if (!this.prototype[`_${name}_as_json`]) { | |
this.prototype[`_${name}_as_json`] = function () { | |
if (this.state[name]) { | |
return this.state[name].asJSON(); | |
} | |
}; | |
} | |
if (!(name in this.prototype)) { | |
Object.defineProperty(this.prototype, name, { | |
key : name, | |
enumerable : false, | |
configurable: true, | |
get : function () { | |
return this.state[name] || new targetClass({id: defaultID}); | |
} | |
}); | |
} | |
} | |
static find(id) { | |
if (!this._instances) return null; | |
return this._instances[parseIntOrNull(id)]; | |
} | |
static isEncode(value) { | |
return _.any([is.string, is.number, is.boolean, is.date, is.null, is.undefined], (m) => { | |
return m.call(is, value); | |
}); | |
} | |
constructor(state) { | |
this.state = {}; | |
this.update(state); | |
if (!this.constructor._instances) this.constructor._instances = {}; | |
this.constructor._instances[this.id] = this; | |
} | |
update(state) { | |
_.each(state || {}, (value, key) => { | |
if (this[`_update_${key}`]) { | |
this[`_update_${key}`](value); | |
} else { | |
this.state[key] = value; | |
} | |
}); | |
} | |
destroy(state) { | |
_.each(state || {}, (value, key) => { | |
if (this[`_destroy_${key}`]) { | |
this[`_destroy_${key}`](value); | |
} | |
}); | |
} | |
toObject() { | |
return _.object(_.map(_.keys(this.state), (key) => { | |
if (this[`_get_${key}`]) { | |
return [key, this[`_get_${key}`]()]; | |
} else { | |
return [key, this.state[key]]; | |
} | |
})); | |
} | |
asJSON() { | |
let dict = _.map(this.state, (value, key) => { | |
if (this[`_${key}_as_json`]) { | |
return [key, this[`_${key}_as_json`]()]; | |
} else { | |
if (BaseModel.isEncode(value)) | |
return [key, value]; | |
} | |
}); | |
return _.object(_.compact(dict)); | |
} | |
_update_id(v) { | |
this.state.id = parseIntOrNull(v); | |
} | |
get id() { | |
return (this.state || {}).id; | |
} | |
} | |
export default BaseModel; |
Author
mosson
commented
Jan 21, 2016
'use strict';
import _ from 'lodash';
import is from 'is_js';
import assign from 'object-assign';
import moment from 'moment';
import Dispatcher from 'dispatchers/common/Dispatcher';
import Constant from 'constants/surveys/AppConstants';
import BaseModel from 'models/BaseModel';
import User from 'models/User';
import Account from 'models/Account';
import Message from 'models/Message';
import Notification from 'models/Notification';
import Survey from 'models/Survey';
import AbstractStore from 'stores/AbstractStore';
class AppProxy extends BaseModel {
get surveys() {
return _.values(this.state.surveys).sort((a, b) => {
return moment(b.created_at).toDate() < moment(a.created_at).toDate();
});
}
get _isLegacy() {
return this.state._isLegacy;
}
get _isNotification() {
return this.state._isNotification;
}
get _filterColor() {
return this.state._filterColor;
}
get _isSearch() {
return this.state._isSearch;
}
get _isList() {
return this.state._isList;
}
get _isColorEditor() {
return this.state._isColorEditor;
}
get _isCreateModal() {
return this.state._isCreateModal;
}
get _surveysOffset() {
return this.state._surveysOffset || 0;
}
get _isSurveyQuerying() {
return this.state._isSurveyQuerying;
}
get _isMoreSurveys() {
if (this.state._isMoreSurveys === undefined) {
return true;
} else {
return this.state._isMoreSurveys;
}
}
get _q() {
return this.state._q;
}
}
AppProxy.hasOne('user', User);
AppProxy.hasOne('account', Account);
AppProxy.hasOne('survey', Survey);
AppProxy.hasMany('messages', Message);
AppProxy.hasMany('notifications', Notification);
AppProxy.hasMany('surveys', Survey);
class AppStore extends AbstractStore {
constructor(key) {
super(key);
this._state = new AppProxy();
}
registration() {
return {
[Constant.ACTIONS.UPDATE] : this.update.bind(this),
[Constant.ACTIONS.DESTROY] : this.destroy.bind(this),
[Constant.ACTIONS.CHANGE_QUERY]: this.changeQuery.bind(this)
};
}
trigger() {
this.emit(Constant.EVENTS.CHANGED);
}
update(payload) {
this._state.update(payload.data);
this.trigger();
}
destroy(payload) {
this._state.destroy(payload.data);
this.trigger();
}
changeQuery(payload) {
this._state.destroy({
surveys: _.map(this._state.surveys, (survey) => {
return {
id : survey.id,
_destroyed: true
};
})
});
this._state.update(assign(payload.data, {_isMoreSurveys: true, _surveysOffset: 0}));
this.trigger();
}
get state() {
return this._state.toObject();
}
}
export default AppStore;
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment