基于MVVM框架的XUUI MoreComplex案例

基于MVVM框架的XUUI MoreComplex案例

Tutorial_MoreComplex — 下拉框与 Lua 表格操作

与 HelloWorld 最大的不同:Dropdown 的 options 数据源

MoreComplex 引入了一个新组件Dropdown(下拉框),它需要两种数据:

数据作用消费方式
data.options下拉列表的选项内容DropdownOptionsAdapter(DataConsumer<LuaTable>)
data.select当前选中的索引(从 0 开始)DropdownAdapter(DataConsumer<int> + DataProducer<int>)

data.options 有什么用

data={options={'vegetables','meat'},-- 下拉列表显示的内容select=0,-- 当前选中第 0 项('vegetables')}

data.options是一个 Lua table,会被DropdownOptionsAdapter消费:

publicclassDropdownOptionsAdapter:AdapterBase<Dropdown>,DataConsumer<LuaTable>{publicLuaTableValue{set{Target.options.Clear();value.ForEach<int,string>((k,v)=>{Target.options.Add(newDropdown.OptionData(v));});}}}

引擎绑定时的数据流:

初始化: observe:getter("options")(data) → {'vegetables', 'meat'} → DropdownOptionsAdapter.Value = LuaTable → Dropdown 显示 "vegetables"、"meat" 两个选项 用户选中第二项 "meat": → DropdownAdapter.OnValueChange(1) ← 索引从 0 开始 → data.select = 1 写回响应式数据 → computed.message 里读取 options[data.select + 1] → "meat"

没有 BindTo,那怎么绑定的?

data.options并不需要写 BindTo 字符串。它的绑定是通过DropdpownOptionsAdapter 本身继承自 AdapterBase来完成的。

查看 AdapterBase.cs:

publicclassAdapterBase:MonoBehaviour{[TextArea]publicstringBindTo;}

所以 DropdownOptionsAdapter 也能设置 BindTo。实际上在场景中你需要给它设置BindTo = "options"。而data.select则由另一个 DropdownAdapter(同样挂载在 Dropdown 上)设置BindTo = "select"

注:Dropdown 组件上挂了两个适配器 — 一个 DropdownOptionsAdapter(BindTo = “options”)负责选项列表,一个 DropdownAdapter(BindTo = “select”)负责选中值和交互。


add_option 命令:为什么需要 observeable.raw

这是第二个关键不同。命令里操作 Lua 表格时有个坑:

add_option=function(data)localtmp=observeable.raw(data.options)-- 先解包成普通表table.insert(tmp,'Option #'..(#tmp+1))-- 操作普通表data.options=tmp-- 赋值回去,触发响应end,

为什么要 raw?

data.optionsobserveable.new()包装过,是个带 metatable 的响应式对象。Lua 的table.insert对这种表不生效(它操作的是 metatable 背后隐藏的_obj,不会触发 __newindex)。

所以步骤必须是这样:

data.options (响应式表) → observeable.raw() → tmp (普通 Lua 表,可正常操作) → table.insert(tmp, 'Option #3') → tmp = {'vegetables', 'meat', 'Option #3'} → data.options = tmp (赋值回去,触发 __newindex → UI 刷新)

如果跳过observeable.raw直接table.insert(data.options, ...),数据改了但 UI 不会更新。


场景设置要点

在 MoreComplex 场景的 Canvas 下,你需要:

GameObject适配器BindTo
DropdownDropdownAdapter"select"
DropdownDropdownOptionsAdapter"options"
TextTextAdapter"message"
Button(添加选项)ButtonAdapter"add_option"

下拉框绑定了两个适配器,一个管选项内容、一个管选中索引。


总结

概念说明
data.options下拉框的选项数据源,被 DropdownOptionsAdapter 消费
data.select选中索引,DropdownAdapter 双向绑定
observeable.raw()操作响应式 Lua 表前必须先解包,改完再赋回去