Skip to content

数据绑定

xuwhale6 edited this page Mar 3, 2021 · 9 revisions

一、简介

ArgoUI提供数据绑定功能,构造model数据,并绑定View,即可通过修改model值同步更新UI。

--声明model
model(userData)

ui{
    --layout views

}

local function preview()
    --构造model数据 
end

二、model声明

model(userData)

三、model使用

  • 绑定基本属性

--[model名].[属性名],如:
model(userData)
ui {
    Label().text(userData.name),
    ImageView().image(userData.avatar)
    .width(50)
    .height(50)
}
function preview()
    userData.name = "MlnUI"
    userData.avatar = "https://s.momocdn.com/w/u/others/2019/10/18/1571393657050-mls_header.png"
end
  • watch:观察model属性

watch(var, filter, func(new))

观察对象, 普通watch 监听最后一个key的值变化 a.b.c 只有c变化时才走回调

---@param var 组件属性   
---@param filter 只监听native端或lua或全部的修改变化,如下枚举: 
---WatchContext.NATIVE: 原生端改变值引起的变化 eg: watch_from_native   
---WatchContext.LUA: lua端改变值引起的变化 eg: watch_from_lua   
---@param fun(new) newkey的新值     

watchValue(var, filter, func(new))

观察对象, a.b.c b/c的变化都会走回调

model(SearchBarModel)
model(tempModel)
---
--- UI
ui {
    --- layout views
    HStack()
    .bgColor(Color(0x999999))
    .cornerRadius(50)
    .padding(0, 20, 0, 20)
    .widthPercent(100)
    .crossAxis(CrossAxis.CENTER)
    .subs(
        EditTextView(SearchBarModel.text).singleLine(true)
        .grow(1)
        .textColor(Color(0xffffff)).left(5).right(10)
        .placeholderColor(Color(0x6e6e6e)).placeholder("请输入")
        .padding(15, 10, 15, 10)
        .setEndChangedCallback(function(text)
            if text == SearchBarModel.text then
                return
            end
            SearchBarModel.text = text
        end)
        ,
        ImageView().ID(clearImg)
        .width(24)
        .height(24)
        .display(false)
        .image("https://s.momocdn.com/w/u/others/custom/lua/vchat/movie/icon-clear.png")
        .onClick(function()
            SearchBarModel.text = ""
        end)
        .watch(SearchBarModel.text, WatchContext.LUA, function(new)
            --观察SearchBarModel.text
            print("watch->SearchBarModel.text=", new)
            clearImg.display(#new ~= 0)
        end)
    )
    ,
    Label("watch_test").top(20)
    .padding(10, 20, 10, 20)
    .bgColor(Color(0x6e6e6e))
    .onClick(function()
        tempModel = {
            name = "Jack",
            age = 66
        }
    end)
    .watch(function()
        --初始化时回调
        print("watch-->")
    end)
    .watch(tempModel, function()
        --不加fliter,默认只监听对方的值修改。
        --如lua修改model,原生可以监听到;原生修改model,lua可以监听到。
        print("watch-->",WatchContext.NATIVE)
    end)
    .watch(tempModel, WatchContext.LUA, function(context)
        print("watch-->tempModel")
    end)
    .watch(tempModel.name, WatchContext.LUA, function(context)
        --watchValue:直接为key重新赋值时回调,如上改变tempModel,不走该回调
        print("watch-->tempModel.name")
    end)
    .watchValue(tempModel.name, WatchContext.LUA, function(context)
        --watchValue:只要key值被重新赋值就回调,如上改变tempModel,监听tempModel.name,走该回调
        print("watchValue-->tempModel.name")
    end)
}.safeArea(SafeArea.TOP)

---
--- preview
local function preview()
    SearchBarModel.text = ""
    tempModel = {
        name = "Tony",
        age = 20
    }
end

注意⚠️:watch 回调 和值是否改变无关。

  • 绑定列表

--1.bindData方法绑定
--List().bindData(userData.list)
--2.构造方法传入model
--List(userData.list)

--demo如下:
--1.bindData方法绑定
--List().bindData(userData.list)
--2.构造方法传入model
--List(userData.list)

--demo如下:
WHITE = Color(255, 255, 255, 1)
PURPLE = Color(100, 100, 200, 1)

model(userData)

mLabel(mark_data(str)) {
    Label(str).padding(12, 18, 12, 18)
    .left(10)
    .bgColor(PURPLE)
    .textColor(WHITE)
}

mCell(mark_data(item)) {
    mLabel(item.title)
}
---
--- UI
ui {
    List()
    .height(250).top(10)
    .bgColor(PURPLE)
    .bindCell(function(item)
        return mCell(item)
    end)
    .bindData(userData.list)
}

---
--- preview
function preview()
    local data = {}
    for i = 1, 5 do
        local temp = {}
        temp.title = "" .. i .. ""
        data[i] = temp
    end
    userData.list = data
end
  • forEach绑定

model(tableModel)

mLabel(mark_data(str), mark_data(bgColor)) {
    Label(str)
    .textColor(Color(255, 255, 255, 0.8))
    .padding(3, 5, 3, 5)
    .bgColor(bgColor)
    .fontSize(10)
}
---
--- UI
ui {
    --- layout views
    HStack()
    .widthPercent(100)
    .bgColor(Color(220, 230, 200, 1))
    .subs(
        tableModel.list.forEach(function(item, index)
            --item:model中第index个元素
            --index:下标
            return mLabel(item.text, item.color)
        end)
    )
}

---
--- preview
local function preview()
    tableModel.list = {
        { text = "0元配送", color = Color(100, 100, 200, 0.8) },
        { text = "支持自取", color = Color(100, 120, 200, 0.8) },
        { text = "食无忧", color = Color(140, 120, 200, 0.8) },
        { text = "津贴2元", color = Color(180, 150, 100, 0.8) },
        { text = "会员专享", color = Color(180, 100, 100, 0.8) },
        { text = "首单立减", color = Color(150, 60, 100, 0.8) }
    }
end
点击展开完整demo
WHITE = Color(255, 255, 255, 1)
PURPLE = Color(100, 100, 200, 1)

model(userData)

mLabel(mark_data(str)) {
    Label(str).padding(12, 18, 12, 18)
    .left(10)
    .bgColor(PURPLE)
    .textColor(WHITE)
}

mCell(mark_data(item)) {
    mLabel(item.title)
}
---
--- UI
ui {
    --- layout views
    VStack().subs(

        HStack().top(100)
        .crossAxis(CrossAxis.CENTER)
        .subs(

            ImageView(userData.avatar)
            .width(50)
            .height(50)
            .bind(function()
                --当userData.showAvater值改变时,将执行 display 方法。
                img.display(userData.showAvater)
            end)    .ID(img)
            ,
            Label(userData.name).left(10)
            ,
            Label("点我隐藏头像").ID(toggleHeader)
            .padding(12, 18, 12, 18)
            .left(10)
            .bgColor(PURPLE)
            .textColor(WHITE)
            .onClick(
                function()
                    userData.showAvater.toggle()
                    if userData.showAvater then
                        toggleHeader.text("点我隐藏头像")
                    else
                        toggleHeader.text("点我显示头像")
                    end
                end)
        )
        ,
        List().ID(list)
        .height(250).top(10)
        .bgColor(PURPLE)
        .bindCell(function(item)
            return mCell(item)
        end)
        .bindData(userData.list)
    )
}

---
--- preview
function preview()
    userData.name = "MlnUI"
    userData.avatar = "https://s.momocdn.com/w/u/others/2019/10/18/1571393657050-mls_header.png"
    userData.showAvater = true
    local data = {}
    for i = 1, 5 do
        local temp = {}
        temp.title = "" .. i .. ""
        data[i] = temp
    end
    userData.list = data
end

四、model与原生互通

1. 打包生成model

打包成功后,会在工程目录中生成对应的lua文件和OC类及java类。

2. 使用

  • Android

  1. 将打包生成的lua文件和java类拷贝到Android工程中
  2. 新建Activity加载这个lua文件
FrameLayout frameLayout = new FrameLayout(this);
setContentView(frameLayout);

instance = new MMUIInstance(this, true, true);
instance.setContainer(frameLayout);

InitData initData = new InitData("file://android_asset/model.lua");
instance.setData(initData);
  1. 绑定数据源
--使用打包生成的javaBean,构造数据源
UserData data = new UserData();
data.setName("MlnUI");
data.setAvatar("https://s.momocdn.com/w/u/others/2019/10/18/1571393657050-mls_header.png");

ObservableList<StuData> list = new ObservableList<>();
for (int i = 1; i < 6; i++) {
     StuData stu = new StuData();
     stu.setTitle("第" + i + "行");
     list.add(stu);
}
data.setList(list);
--绑定数据源
MMUIBinding binding = new MMUIBinding(instance);
binding.bind("userData", data);
  • iOS

  1. 将打包生成的lua文件和OC类拷贝到iOS工程中

  2. 加载lua文件

NSString *entryfile = @"demo.lua";
MLNKitViewController *viewController = [[MLNKitViewController alloc] initWithEntryFilePath:entryfile];
  1. 绑定数据源
--bindData  绑定数据
self.model  = [self buildModel];
[viewController bindData:self.model forKey:@"userData"];

--构造数据源
-(NSMutableArray *)buildModel{

        MLNUIDEMOTESTUserData *model = MLNUIDEMOTESTUserData.new;
        model.name = @"MlnUI";
        model.avatar = @"https://s.momocdn.com/w/u/others/2019/10/18/1571393657050-mls_header.png";
      
        NSMutableArray  *array =  NSMutableArray.new;
        for (int i = 1; i < 6; i++) {
            MLNUIDEMOTESTUserDatalist *item = MLNUIDEMOTESTUserDatalist.new;
            item.title = [NSString stringWithFormat:@"第%d行", i];
            [array addObject:item];
        }
        
        model.list =  array;
        return model;
    }
  1. push页面
[self.navigationController pushViewController:viewController animated:YES];
Clone this wiki locally