zoukankan      html  css  js  c++  java
  • 灵光乍现,lua数据绑定

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

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

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

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

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

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

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

    实现方法:

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

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

    我TM真是天才。。

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

     1 local function bindable(init)
     2     local t = {}
     3     local mt
     4     mt = {
     5         bind____ = {},
     6 
     7         __index = function(table, key)
     8             return mt[key]
     9         end,
    10 
    11         __newindex = function(table, key, value)
    12             local v_old = mt[key]
    13             if v_old == value then
    14                 return
    15             end
    16             mt[key] = value
    17             local slots = mt.bind____[key]
    18             if slots then
    19                 for _, v in ipairs(slots) do
    20                     v(value, v_old)
    21                 end
    22             end
    23         end
    24     }
    25     setmetatable(t, mt)
    26     for k, v in pairs(init) do
    27         t[k] = v
    28     end
    29     return t
    30 end
    31 
    32 local function bind(table, key, func)
    33     local binds = table.bind____
    34     binds[key] = binds[key] or {}
    35     local bind = binds[key]
    36     bind[#bind+1] = func
    37     return #bind
    38 end
    39 
    40 local t = bindable({
    41     x = 123,
    42     y = 456
    43 })
    44 
    45 local tag = bind(t, "x", function(val, old)
    46     print("x changed:", "new:", val, "old:", old)
    47 end)
    48 
    49 t.x = 250
    50 t.x = 100
    View Code

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

    2016.2.17 更新

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

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

  • 相关阅读:
    用localeCompare实现中文排序
    点击一个链接同时打开两个页面
    汉字和Unicode编码互转
    javascript中document学习
    javascript页面表格排序
    JavaScript 仿LightBox内容显示效果
    JavaScript面向对象的简单介绍
    JavaScript键盘上下键的操作(选择)
    关于clientWidth、offsetWidth、clientHeight、offsetHeigh
    动态(按需)加载js和css文件
  • 原文地址:https://www.cnblogs.com/wolfred7464/p/5193766.html
Copyright © 2011-2022 走看看