利用lua元表__newindex可以实现数据变化监测,在需要的地方添加数据监听。
local function _createHelper(target)
local obj = {};
obj.__setCallbacks__ = {};
function obj:addObserver(key,callback)
if key==nil or type(callback)~="function" then
return
end
local arr = self.__setCallbacks__[key]
if arr==nil then
self.__setCallbacks__[key] = {}
arr = self.__setCallbacks__[key]
end
arr[#arr+1] = callback
callback(target[key],nil)
return #arr
end
function obj:removeObserver(key,handlerId)
if key==nil or type(handlerId)~="number" then
return
end
local arr = self.__setCallbacks__[key]
if arr==nil then
return
end
arr[handlerId] = nil
end
function obj:_exec(key,val,old)
local arr = self.__setCallbacks__[key] or {}
for k,v in pairs(arr) do
if v then
v(val,old)
end
end
end
return obj
end
local function createProxy(target)
local obj = _createHelper(target)
local handler = {
set = function(target,key,value,oldValue)
obj:_exec(key,value,oldValue)
end,
get = function(target,key,val)
end
}
local ret = setmetatable(obj,{
__index = function (t,key)
handler.get(target,key,target[key])
return target[key]
end,
__newindex = function (t,key,val)
if target[key] then
local old = target[key]
target[key] = val
handler.set(target,key,val,old)
else
rawset(t,key,val)
end
end
})
return ret;
end
return createProxy
测试:
local obj = {
a = 1,
b = "hello"
}
local _proxy = createProxy(obj)
local id = _proxy:addObserver("b",function (val,old)
print("---------1111 ",val,old)
end)
--原始obj对象没有g字段,所以监听无效
local id2 = _proxy:addObserver("g",function (val,old)
print("---------2222 ",val,old)
end)
_proxy.b = "bbb"
--删除监听后,监测失效
_proxy:removeObserver("b",id)
_proxy.b = "b22"
_proxy.ggg = "ggg"
输出
---------1111 hello nil
---------2222 nil nil
---------1111 bbb hello