织梦 茶叶网站,制作企业网站教程,wordpress文字围绕图片,老客户网站建设我们现在有一个 角色属性类叫heroModel,内容如下,当heroModel中的等级发生变化的时候#xff0c;我们需要刷新界面显示等级信息#xff0c;通常我们是在收到等级升级成功的协议的时候#xff0c;发送一个事件#xff0c;UI界面接受到这个事件的时候#xff0c;刷新一下等级…我们现在有一个 角色属性类叫heroModel,内容如下,当heroModel中的等级发生变化的时候我们需要刷新界面显示等级信息通常我们是在收到等级升级成功的协议的时候发送一个事件UI界面接受到这个事件的时候刷新一下等级信息如果不采用全局事件的方式该怎么处理呢 我们能不能监听HeroModel的level这个属性给这个属性绑定一个监听方法当这个属性发生变化的时候自动执行这个监听方法执行一些刷新操作。
local heroModel {id 1001,star 1,level 1, life 1000,atk 100,def 10,}
我们知道lua有两个比较常见的原方法 __index 和 __newindex__index是 元表提供的表对象内部数据获取元方法__newindex是当对表中不存在的元素进行赋值时会被调用。当我们从heroModel中获取某一个属性值的时候会先从heroModel中取值如果heroModel中不存在该值则会从原表中取值同样当我们给heroModel赋值的时候会先判断heroModel是否存在该属性如果存在直接赋值不存在则从原方法 __newindex中进行赋值。加入heroModel中不存在level这个属性那么我们给它赋值的时候肯定会调用原方法__newindex ,这个时候我们就可以在这个原方法里面赋值的时候进行判断属性level是否发生变化如果发生了变化 则执行一个回调方法
简单演示如下
local heroModel {id 1001, star 1, level1}---创建原表local metaTable {}metaTable.newInfo {} --保存新创建的属性值metaTable.bindDataList {} --存储回调方法metaTable.__index function(t , k)printError(get .. k)local res metaTable.newInfo[k]return resendmetaTable.__newindex function(t, k, v)printError(set .. k .. .. tostring(v))if (not metaTable.newInfo[k] or metaTable.newInfo[k] ~ v) and metaTable.bindDataList[k] ~ nil thenlocal callback metaTable.bindDataList[k]callback()endmetaTable.newInfo[k] vreturn vend-- 将heroModel中的属性赋值到原表并清空heroModel,这样操作之后只要给heroModel进行赋值就会执行它的原方法 __newindexfor k, v in pairs(heroModel) dometaTable.newInfo[k] vheroModel[k] nilend-- 设置元表setmetatable(heroModel, metaTable)-- 绑定回调方法metaTable.bindDataList[level] function()printError(level 值发生了变化)end--测试printError(----test---)printError(level 初始值 ..tostring(heroModel.level)) --没有更新赋值时候进行调用heroModel.level 10 --通过__newindex 刷新属性值并执行回调heroModel.level 11local b heroModel.level --通关__index 获取新属性值printError(level新值 .. b)heroModel.kkk 111 --通过__newindex 创建新属性值printError(heroModel.kkk) --通关__index 获取新属性值输出结果 完整代码
DataBindModel {}---class DataBindModel:nil
local DataBindModel DataBindModel---给实例添加绑定 内部方法 不要手动调用
---param target dataBindInfo
function DataBindModel:__bindIns(target)if (target.dataBindvars) thenreturnendlocal dataBindvars {}local mateTable getmetatable(target)setmetatable(dataBindvars, mateTable)for k, v in pairs(target) dodataBindvars[k] vtarget[k] nilendtarget.dataBindvars dataBindvarstarget.bindInfo__ {}target.isBind falsetarget.oldMateTable mateTablelocal settable { __index function(t, key)return dataBindvars[key]end }settable.__newindex DataBindModel.__newindexsetmetatable(target, settable)
endfunction DataBindModel:unBindIns(target)if (not target.dataBindvars) thenreturnendlocal dataBindvars target.dataBindvarslocal mateTable target.oldMateTabletarget.oldMateTable niltarget.bindInfo__ niltarget.isBind niltarget.dataBindvars nilsetmetatable(target, mateTable)for k, v in pairs(dataBindvars) dotarget[k] vend
endfunction DataBindModel:newIndex(key)return self.dataBindvars[key]
endfunction DataBindModel:__newindex(key, var)local vars self.dataBindvarslocal oldValue vars[key]vars[key] varif (self.isBind) thenif (oldValue ~ var) thenlocal bindInfo__ self.bindInfo__local bindData bindInfo__[key]if (bindData) thenlocal tempBindData {}for i, bdata in ipairs(bindData) dotable.insert(tempBindData, bdata)endfor i, bdata in ipairs(tempBindData) dobdata.callBack(var, bdata, self)endtempBindData nilendendendend---param target any model
---param bindInfo dataBindInfo
function DataBindModel:bindKey(target, bindInfo)if not target thenprintWarningColor(FFB500FF, dataModel is nil)returnendif (not target.dataBindvars) thenself:__bindIns(target)endlocal bindInfo__ target.bindInfo__local bindData bindInfo__[bindInfo.key]if (not bindData) thenbindData {}bindInfo__[bindInfo.key] bindDataendtarget.isBind truelocal uiNode bindInfo.uiNodeif (uiNode and not tolua.isnull(uiNode)) then---type CS.NodeEventListenerlocal nodeEventListener uiNode:GetComponent(typeof(CS.NodeEventListener))if not nodeEventListener thennodeEventListener uiNode.gameObject:AddComponent(typeof(CS.NodeEventListener))bindInfo.nodeEventHandle function()self:unBindKey(target, bindInfo)endif nodeEventListener.destroyCallback thennodeEventListener.destroyCallback nodeEventListener.destroyCallback bindInfo.nodeEventHandleelsenodeEventListener.destroyCallback bindInfo.nodeEventHandleendendendtable.insert(bindData, bindInfo)
end---param target any
---param bindInfo dataBindInfo
function DataBindModel:unBindKey(target, bindInfo)if (not target.dataBindvars) thenreturnendlocal bindInfo__ target.bindInfo__local bindData bindInfo__[bindInfo.key]if (bindData) thenlocal index table.indexof(bindData, bindInfo)if (index) thentable.remove(bindData, index)local uiNode bindInfo.uiNodeif (uiNode and not tolua.isnull(uiNode)) thenlocal nodeEventHandle uiNode:GetComponent(typeof(CS.NodeEventListener))if nodeEventHandle thennodeEventHandle.destroyCallback nodeEventHandle.destroyCallback - bindInfo.nodeEventHandleendendendif (#bindData 0) thenbindInfo__[bindInfo.key] nilendendlocal count 0;for k, v in pairs(bindInfo__) docount count 1;break ;endif (count 0) thenself:unBindIns(target)end
end---param bindDataInfos dataBindInfo
function DataBindModel:bindKeys(target, bindDataInfos)for i, data in ipairs(bindDataInfos) doself:bindKey(target, data)end
end---param bindDataInfos dataBindInfo
function DataBindModel:unBindKeys(target, bindDataInfos)for i, data in ipairs(bindDataInfos) doself:unBindKey(target, data)end
endreturn DataBindModel调用
注DataBindModel 是一个全局table
local heroModel {id 1001, star 1, level1}
local bindDatas {key level, callBack function(value, bindInfo, model)-- 执行刷新逻辑self:checkRed()end
}
DataBindModel:bindKeys(heroModel, bindDatas)