MVVM的核心就是数据驱动,数据驱动的核心就是数据绑定。

我一直在思考,如何使用lua做一个数据绑定的功能,仔细思考一下,数据绑定需要做到的功能很简单,就是当一个数据改变时,能主动回调一个或多个函数就好了。但是实现起来却不是那么简单。。

这个问题我苦想了几个月了,也做了几个版本出来,(代码不贴了),但是都不够完美,主要思路是读写数据使用get和set函数,既然是主动调用函数,实现回调其他函数自然就没问题了,再简化一点无非是对每个字段都可以自动生成get和set函数,但是很明显,这种方案完全自己使用还行,一旦结合其他库(哪怕是官方库),就做不到主动回调函数了。(例如官方库的sort函数,使用“x=123”的形式为x赋值的,并不是调用“setX(123)”呀)

所以还需要解决的除了主动回调函数外,还得能hook住每次“=”的调用。

然后我去思考元表的方案,始终没能想出一个好的方案。(智商感人)

而就在今天晚上,真的是灵光乍现啊,是哪位天使大姐被我感动了,来给我指点迷津吗。

必须写篇博客,就当是还愿了。

实现方法:

元表的__index和__newindex两个元方法,会lua的应该都熟悉了,就不啰嗦了。这两个元方法会在读写表中字段的时候触发,但是触发这两个元方法都需要一个条件:表中不存在某个字段。

接下来就简单了,只要始终保持表中不存在要绑定的字段就好了。

我TM真是天才。。

话不多说,上代码,这是我今晚随手写下的代码,真正使用的时候再稍微封装一下就可以了,几乎完美:

 local function bindable(init)
local t = {}
local mt
mt = {
bind____ = {}, __index = function(table, key)
return mt[key]
end, __newindex = function(table, key, value)
local v_old = mt[key]
if v_old == value then
return
end
mt[key] = value
local slots = mt.bind____[key]
if slots then
for _, v in ipairs(slots) do
v(value, v_old)
end
end
end
}
setmetatable(t, mt)
for k, v in pairs(init) do
t[k] = v
end
return t
end local function bind(table, key, func)
local binds = table.bind____
binds[key] = binds[key] or {}
local bind = binds[key]
bind[#bind+] = func
return #bind
end local t = bindable({
x = ,
y =
}) local tag = bind(t, "x", function(val, old)
print("x changed:", "new:", val, "old:", old)
end) t.x =
t.x =

------------------------------------------------

2016.2.17 更新

我封装了一个完整版,放在了https://github.com/Anti-Magic/rdatabinding

代码只有100行,支持各种花式绑定,也支持取消绑定

灵光乍现,lua数据绑定的更多相关文章

  1. 灵感乍现!造了个与众不同的Dubbo注册中心扩展轮子

    hello大家好呀,我是小楼. 作为一名基础组件开发,服务好每一位业务开发同学是我们的义务(KPI). 客服群里经常有业务开发同学丢来一段代码.一个报错,而我们,当然要微笑服务,耐心解答. 有的问题, ...

  2. python的解释器spython介绍

    Python解释器spython介绍 简介 出于个人爱好和某种需求,我再16年对python的解释器产生了浓厚兴趣,并且下定决心重新实现一个版本.我个人再游戏服务器开发中,对c++嵌入lua和pyth ...

  3. 从ASP.NET 升级到ASP.NET5(RC1) - 翻译

    前言 ASP.NET 5 是一次令人惊叹的对于ASP.NET的创新革命. 他将构建目标瞄准了 .NET Core CLR, 同时ASP.NET又是对于云服务进行优化,并且是跨平台的框架.很多文章已经称 ...

  4. 最难面试的IT公司之ThoughtWorks代码挑战——FizzBuzzWhizz游戏(C#解法)

    原题 看到那么多人看到前面这么糟粕的代码各种不忍直视后,楼主还是把最终实现放在页首吧.             Console.WriteLine("说出三个不同的特殊数,用','隔开 &q ...

  5. 26 Time Management(转)

    01. There is alway time. Time is priorities. 时间常有.时间优先. 02. Days always fill up. 时间总会有的. Only plan f ...

  6. 《Java4Android》视频学习笔记——为什么用抽象类?

    我们来举个例子,然后引出这个问题的答案: 市面上有 喷墨式打印机 和 针式打印机 这两种形式的打印机,我们需要编程来实现他们的 开机,关机以及打印. 构建父类Printer class Printer ...

  7. You and Your Research(Chinese)

    转自:http://lyxh-2003.iteye.com/blog/434014 这是大科学家Richard Hamming的著名讲演,于1986年在贝尔通讯研究中心给200多名Bellcore的科 ...

  8. Facebook内部分享:26个高效工作的小技巧

    春节假期马上就要结束了,该收收心进入新一年的工作节奏了~分享 26 个高效工作的小技巧,希望对大家有所帮助~(我发现自己只有最后一条执行得很好,并且堪称完美!) 1.时间常有,时间优先. 2.时间总会 ...

  9. img标签src不给路径就会出现边框————记一次二笔的编码经历

    <img/>在src加载失败或没有给的,浏览器会自动给img加上边框. 如下图这样: 产品觉得影响美观,一定要pass掉. 原码是这样: .ctn{ position: relative; ...

随机推荐

  1. Ubuntu 14.04 LTS 与Kylin

    现在是安装了Ubuntu 14.04 LTS 但是通过安装ubuntukylin 这个包居然实现了Kylin--原来这个自主研发还这么方便-呵呵 sudo apt-get install ubuntu ...

  2. java笔记00-目录

    --2013年7月26日17:49:59 学习java已久,趁最近有空,写一个总结: java笔记01-反射:

  3. Wince 设备环境和画笔应用

    本文主要讲到的是画笔应用,在Wince -06环境下,画笔应用很广泛,很有技巧,这里笔者要着重介绍. 设备环境可以用一下图表示,主要是让大家大致了解Wince -06的设备环境,下面在图形舍虚设计中会 ...

  4. 通用函数get和set

    这两个函数在画图时很常用,所有对象都有属性来定义它们的特征,正是通过设定这些属性来修正图形显示的方式.尽管许多属性所有的对象都有,但与每一种对象类型(比如坐标轴,线,曲面)相关的属性列表都是独一无二的 ...

  5. server 2003上为单点登录sso配置映射

    单点登录不是本人做的,代码需要调用类似 http://***.com/login.sso 的地址.要成功调用,需要在IIS设置.sso为后缀的映射项. Win7系统下一设置完,就能成功调用. 但是服务 ...

  6. ubuntu忘记密码,忘记root密码的解决方法

    转载于http://forum.ubuntu.org.cn/viewtopic.php?t=272164 ubuntu的root默认是禁止使用的,在安装的时候也没要求你设置root的密码,和红帽系统系 ...

  7. Android之View方法

    onFinishInflate() 回调方法,当应用从XML加载该组件并用它构建界面之后调用的方法 onMeasure() 检测View组件及其子组件的大小 onLayout() 当该组件需要分配其子 ...

  8. [java学习笔记]java语言基础概述之函数的定义和使用&函数传值问题

    1.函数 1.什么是函数? 定义在类中的具有特定功能的一段独立小程序. 函数也叫做方法 2.函数的格式 修饰符   返回值类型    函数名(参数类型  形式参数1, 参数类型  形式参数2-) { ...

  9. 类似QQ的应用毗邻(Pilin)即时聊天源码

      这个应用是从安卓教程网分享过了的,个人觉得这个还是挺不错的,毗邻(Pilin)即时聊天应用源码,承诺的 基于xmpp openfire asmack 的即时聊天应用,继续完善,现在只完成了文字.表 ...

  10. DEDECMS中,arclist标签

    文档列表  dede:arclist 标签: {dede:arclist flag='h' typeid='' row='' col='' titlelen='' infolen='' imgwidt ...