基于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 有什么用

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

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

csharp 复制代码
public class DropdownOptionsAdapter : AdapterBase<Dropdown>, DataConsumer<LuaTable>
{
    public LuaTable Value
    {
        set
        {
            Target.options.Clear();
            value.ForEach<int, string>((k, v) =>
            {
                Target.options.Add(new Dropdown.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

csharp 复制代码
public class AdapterBase : MonoBehaviour
{
    [TextArea]
    public string BindTo;
}

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

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


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

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

lua 复制代码
add_option = function(data)
    local tmp = 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
Dropdown DropdownAdapter "select"
Dropdown DropdownOptionsAdapter "options"
Text TextAdapter "message"
Button(添加选项) ButtonAdapter "add_option"

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


总结

概念 说明
data.options 下拉框的选项数据源,被 DropdownOptionsAdapter 消费
data.select 选中索引,DropdownAdapter 双向绑定
observeable.raw() 操作响应式 Lua 表前必须先解包,改完再赋回去
相关推荐
czhc11400756638 小时前
7.29:树形;
c#
cm04Z9c918 小时前
C#摸鱼实录——IoC与DI案例详解
开发语言·c#
geovindu14 小时前
CSharp:Chain of Responsibility Pattern
开发语言·后端·设计模式·c#·.net·责任链模式·行为模式
颜x小16 小时前
[C#]泛型类与泛型方法
开发语言·c++·c#
caishenzhibiao16 小时前
顺势交易矩阵主图 同花顺期货通指标
java·c语言·c#
TDengine (老段)17 小时前
TDengine Node.js 与 C# 连接器 — Web 服务与 .NET 集成
大数据·数据库·node.js·c#·.net·时序数据库·tdengine
懒狗跑ai的程序员Brain17 小时前
如何利用粒子系统在unity制作一个烟花(粒子系统学习向)
学习·unity·游戏引擎
河西石头18 小时前
再谈C#的抽象类和接口:从“适配器”到“毛坯房”的设计哲学
开发语言·c#·接口·依赖注入·抽象类·依赖倒挂
颜x小18 小时前
[C#]——接口与继承
开发语言·c++·c#
xcLeigh18 小时前
Unity基础:材质与纹理入门——给物体穿上“衣服“
unity·游戏引擎·材质