mvvm的核心就是資料驅動,資料驅動的核心就是資料繫結。
我一直在思考,如何使用lua做乙個資料繫結的功能,仔細思考一下,資料繫結需要做到的功能很簡單,就是當乙個資料改變時,能主動**乙個或多個函式就好了。但是實現起來卻不是那麼簡單。。
這個問題我苦想了幾個月了,也做了幾個版本出來,(**不貼了),但是都不夠完美,主要思路是讀寫資料使用get和set函式,既然是主動呼叫函式,實現**其他函式自然就沒問題了,再簡化一點無非是對每個欄位都可以自動生成get和set函式,但是很明顯,這種方案完全自己使用還行,一旦結合其他庫(哪怕是官方庫),就做不到主動**函式了。(例如官方庫的sort函式,使用「x=123」的形式為x賦值的,並不是呼叫「setx(123)」呀)
所以還需要解決的除了主動**函式外,還得能hook住每次「=」的呼叫。
然後我去思考元表的方案,始終沒能想出乙個好的方案。(智商感人)
而就在今天晚上,真的是靈光乍現啊,是哪位天使大姐被我感動了,來給我指點迷津嗎。
必須寫篇部落格,就當是還願了。
實現方法:
元表的__index和__newindex兩個元方法,會lua的應該都熟悉了,就不囉嗦了。這兩個元方法會在讀寫表中字段的時候觸發,但是觸發這兩個元方法都需要乙個條件:表中不存在某個字段。
接下來就簡單了,只要始終保持表中不存在要繫結的字段就好了。
我tm真是天才。。
話不多說,上**,這是我今晚隨手寫下的**,真正使用的時候再稍微封裝一下就可以了,幾乎完美:
1view codelocal
function
bindable(init)
2local t ={}
3local
mt4 mt =,
67 __index = function
(table, key)
8return
mt[key]
9end,10
11 __newindex = function
(table, key, value)
12local v_old =mt[key]
13if v_old == value then
14return
15end
16 mt[key] =value
17local slots =mt.bind____[key]
18if slots then
19for _, v in
ipairs(slots) do
20v(value, v_old)
21end
22end
23end24}
25setmetatable
(t, mt)
26for k, v in
pairs(init) do
27 t[k] =v
28end
29returnt30
end31
32local
function
bind(table, key, func)
33local binds =table.bind____
34 binds[key] = binds[key] or
{}35
local bind =binds[key]
36 bind[#bind+1] =func
37return #bind
38end
3940
local t =bindable()
4445
local tag = bind(t, "
x", function
(val, old)
46print("
x changed:
", "
new:
", val, "
old:
", old)
47end)48
49 t.x = 250
50 t.x = 100
2016.2.17 更新
我封裝了乙個完整版,放在了
**只有100行,支援各種花式繫結,也支援取消繫結
解決問題與靈光乍現
怎麼去解決乙個非常棘手的問題?這是個極難回答的問題,很難在沒有任何背景的情況下去 我想說的也是不去預設任何背景地去討論它。在給出解決方案的前一步大概率的情況下應該是找到問題的原因,否則便是不斷的試探,窮盡可能的解決策略,這不是本文要討論的方法。那麼如何去找到問題的原因呢?這又是乙個棘手的問題。試探的...
資料繫結 多路繫結MultiBinding
有時候ui要顯示的資訊又不止乙個資料 決定,就需要使用multibinding,multibinding具有乙個名為bindings的屬性,其型別是collection,通過這個屬性multibinding把一組binding物件聚合起來,處在這個集合中的binding物件可以擁有自己的資料校驗與轉...
Spring MVC資料繫結 複雜資料繫結
接上篇spring mvc資料繫結 簡單資料繫結 1 繫結包裝pojo 所謂的包裝pojo,就是在乙個pojo中包含另乙個簡單pojo。例如,在訂單物件中包含使用者物件。這樣在使用時,就可以通過訂單查詢到使用者資訊。1.在po包下新建乙個orderspojo public class orders2...