UNPKG

gfs-react-dm

Version:

简化react和redux的繁杂流程,更简单的数据操作管理

219 lines (192 loc) 7.65 kB
'use strict'; exports.__esModule = true; exports.Model = Model; exports.getActionTypes = getActionTypes; exports.getModels = getModels; exports.emptyModels = emptyModels; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var _gfsReactReduxTwowayBinding = require('gfs-react-redux-twoway-binding'); var _immutable = require('immutable'); var _immutable2 = _interopRequireDefault(_immutable); /** * 实体、数据模型,model中的方法和属性都该设置成静态类型 * @class Model * */ //需要一个队列保存model var __gfs_mvc_m_list = {}; var __gfs_mvc_m_actiontypes = {}; var DEFAULT_METHOD_FIX = '$$'; exports.DEFAULT_METHOD_FIX = DEFAULT_METHOD_FIX; var DEFAULT = 'default'; exports.DEFAULT = DEFAULT; function getField(data, path) { try { var newpath = path.concat(); for (var i = 0, len = newpath.length, p, v; i < len; i++) { //如果path不是最后一个 if (i != len) { p = newpath.slice(0, i + 1); v = data.getIn(p); if (!v) { var _Immutable$fromJS; data = typeof v == 'undefined' ? data.mergeIn(p.slice(0, p.length - 1), _immutable2['default'].fromJS((_Immutable$fromJS = {}, _Immutable$fromJS[p[p.length - 1]] = {}, _Immutable$fromJS))) : data.setIn(p, {}); } } } } catch (ex) { console && console.warn && console.warn(ex); } return data; } function merger(prev, next) { if (_immutable2['default'].List.isList(prev) && _immutable2['default'].List.isList(next)) { return next; } if (prev && prev.mergeWith) { return prev.mergeWith(merger, next); } return next; } function getOriginData(data) { if (data) { if (typeof data.toJS == 'undefined') { return _immutable2['default'].fromJS(data); } } return data; } var curl = { del: function del(data, action) { return getOriginData(data).deleteIn(action.path); }, update: function update(data, action) { data = getOriginData(getField(data, action.path)); if (typeof action.data === 'string' && action.path) { return data.setIn(action.path, action.data); } action.data = _immutable2['default'].fromJS(action.data); return action.path ? data.mergeDeepIn(action.path, action.data) : data.mergeDeep(action.data); }, updateWith: function updateWith(data, action) { data = getOriginData(data); if (typeof action.data === 'string' && action.path) { return data.setIn(action.path, action.data); } action.data = _immutable2['default'].fromJS(action.data); return data.mergeWith(action.merge ? action.merge : merger, action.data); }, save: function save(data, action) { data = getOriginData(getField(data, action.path)); return data.setIn(action.path, action.isImmutable ? _immutable2['default'].fromJS(action.data) : action.data); }, insert: function insert(data, action) { data = getOriginData(getField(data, action.path)); return data.setIn(action.path, action.isImmutable ? _immutable2['default'].fromJS(action.data) : action.data); }, query: function query(data) { return data; }, findOne: function findOne(data, action) { return getOriginData(data).getIn(action.path); }, find: function find(data, action) { return getOriginData(data).getIn(action.path); } }; function implement() { var target = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; var modelName = arguments.length <= 1 || arguments[1] === undefined ? '' : arguments[1]; var param = arguments.length <= 2 || arguments[2] === undefined ? { property: {}, method: {} } : arguments[2]; var fix = arguments.length <= 3 || arguments[3] === undefined ? '' : arguments[3]; var property = param.property; var method = param.method; if (fix) { fix += DEFAULT_METHOD_FIX; } for (var item in target) { if (!(target[item] instanceof Function)) { property[item] = target[item]; } else { method['' + fix + modelName + DEFAULT_METHOD_FIX + item] = target[item].bind(target); //__gfs_mvc_m_actiontypes[`${fix}${modelName}${DEFAULT_METHOD_FIX}${item}`] = `${fix}${modelName}${DEFAULT_METHOD_FIX}}${item}` } } return { property: property, method: method }; } /** * 一个类装饰器,被装饰的类会变成store,默认不需要额外提供对数据操作的方法,在control中默认会提供del、update、insert等数据操作方法;如果有特殊需求无法满足使用场景可按照example中给出的方式自行编写数据处理方法<br /> * <strong style="color:red">注意:model类中`__name`属性必须要有,这是为了能在各个component正常使用model必备的一个属性,必须小写,默认会在字符串后面添加上"model",例如:`static __name='test'`,那么在实际中运用应该是this.props.testmodel</strong> * @method Model * @param target {object} 被包装的对象 * @example * * import {Model} from 'gfs-react-mvc' * //这里由于@为文档关键符号,所以下面将以$代替 * //@Model * $Model class TestModel { //__name必须要有,这是为了能再各个component正常使用model必备的一个属性,必须小写 static __name = 'testmodel' //数据模型 static age = 20 static xq = {} //可以自行定义数据操作方法,在control中通过 //dispatch({ // type:`testmodel$$save`, // data:data //}) //这种方式变更数据,其中type值的组成是通过:类名(全小写)+ 方法名组成 static save(data, action){ if(action.data){ return data.merge(Immutable.fromJS(action.data) ) } } //dispatch({ // type:`testmodel$$del`, // data:data //}) static del(data, action){ if(action.data){ return data.merge(Immutable.fromJS(action.data) ) } } } * */ function Model(target) { var params = {}; //读取字段组成新的对象 if (typeof target.__name == 'undefined') { console && console.warn('[create model error] ', 'Model中必须存在__name属性,并赋予store名称,例如: static __name="testmodel"'); return { modelName: '', store: null }; } var modelName = target.__name.toLowerCase(); if (modelName.indexOf('model') <= -1) { modelName += 'model'; } //取得属性或方法 params = implement(target, modelName); params = implement(curl, modelName, params, DEFAULT); // params = implement(target.prototype,modelName,params) var store = _gfsReactReduxTwowayBinding.createReducer(modelName, _immutable2['default'].fromJS(params.property || {}), params.method); __gfs_mvc_m_list['' + modelName] = store; return { modelName: modelName, store: store }; } function getActionTypes(typeName) { return __gfs_mvc_m_actiontypes[typeName]; } function getModels() { return __gfs_mvc_m_list; } function emptyModels() { __gfs_mvc_m_list = null; //delete __gfs_mvc_m_list }