- import { createReducer } from 'gfs-react-redux-twoway-binding'
- import Immutable from 'immutable'
- /**
- * 实体、数据模型,model中的方法和属性都该设置成静态类型
- * @class Model
- * */
- //需要一个队列保存model
- let __gfs_mvc_m_list = {}
- let __gfs_mvc_m_actiontypes = {}
-
- export const DEFAULT_METHOD_FIX = '$$'
- export const 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 ){
- data = typeof(v)=='undefined' ? data.mergeIn(p.slice(0,p.length-1),Immutable.fromJS({
- [p[p.length-1]]:{}
- }) ) : data.setIn(p,{})
- }
- }
- }
-
- }catch(ex){
- console && console.warn && (console.warn(ex) )
- }
-
- return data
- }
-
- function merger(prev,next){
- if( Immutable.List.isList(prev) && Immutable.List.isList(next)){
- return next
- }
- if(prev && prev.mergeWith){
- return prev.mergeWith(merger,next)
- }
- return next
- }
-
- let curl = {
- del:function(data,action){
- return data.deleteIn(action.path)
- },
- update:function(data,action){
- data = getField(data,action.path)
- if(typeof(action.data) ==='string' && action.path){
- return data.setIn(action.path,action.data)
- }
- action.data = Immutable.fromJS(action.data)
- return action.path ? data.mergeDeepIn(action.path,action.data ) : data.mergeDeep(action.data )
- },
- updateWith:function(data,action){
- //data = getField(data,action.path)
- if(typeof(action.data) ==='string' && action.path){
- return data.setIn(action.path,action.data)
- }
- action.data = Immutable.fromJS(action.data)
- return data.mergeWith(action.merge ? action.merge:merger,action.data )
- },
- save:function(data,action){
- data = getField(data,action.path)
- return data.setIn(action.path,action.isImmutable ?Immutable.fromJS(action.data) : action.data)
- },
- insert:function(data,action){
- data = getField(data,action.path)
- return data.setIn(action.path,action.isImmutable ?Immutable.fromJS(action.data) : action.data)
- },
- query:function(data){
- return data
- },
- findOne:function(data,action){
- return data.getIn(action.path)
- },
- find:function(data,action){
- return data.getIn(action.path)
- }
- }
-
- function implement(target={},modelName='',param={property:{},method:{}},fix=''){
- let property = param.property
- let method = param.method
-
- if(fix){
- fix+=DEFAULT_METHOD_FIX
- }
- for(let 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) )
- }
- }
- }
- * */
- export function Model(target){
- let params={}
- //读取字段组成新的对象
- if(typeof(target.__name) == 'undefined' ){
- console && console.warn('[create model error] ','Model中必须存在__name属性,并赋予store名称,例如: static __name="testmodel"')
- return {
- modelName:'',
- store:null
- }
- }
- let 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)
-
- let store = createReducer(modelName, Immutable.fromJS(params.property||{} ), params.method)
-
- __gfs_mvc_m_list[`${modelName}`]=store
-
- return {
- modelName:modelName,
- store:store
- }
-
- }
-
- export function getActionTypes(typeName){
- return __gfs_mvc_m_actiontypes[typeName]
- }
-
- export function getModels(){
- return __gfs_mvc_m_list
- }
-
- export function emptyModels(){
- __gfs_mvc_m_list = null
- //delete __gfs_mvc_m_list
- }
-
-
-
-