Skip to content

装配ViewModel

xuwhale6 edited this page Jan 26, 2021 · 17 revisions

我们提供自动装配和手动装配来简化ViewModel数据源的赋值。通过简单调用方法即可完成数据装配。

一、自动装配

简介:

一般情况下,我们ViewModel的数据源来自网络请求,因此提供自动装配,可将网络请求返回的json串自动解析作为ViewModel的默认数据。

用法:

1. ag声明式代码中,在preview里实现autoWired方法(方法命名为autoWired+model名,如model名为homeData,则autoWiredhomeData),将json串和ViewModel相关联,并返回ViewModel

--origin:网络请求获取的json数据
--json串和ViewModel对应即可
--如下:取json串中key="data"对应的value解析为viewmodel。根据实际情况自行实现。
function autoWired(origin, viewModel, extra)
        viewModel = origin.data
        return viewModel
    end

2. 打包

3. 打包之后生成的ViewModel提供autoWired方法将网络请求返回的json串自动解析作为ViewModel的默认数据。

--关键代码如下:调用autoWired方法。
--iOS:
[self.model autoWired:_origin extra:nil complete:^(__kindof NSObject * _Nonnull model, NSError * _Nonnull error) {
        printf("装配完毕");
    }];
--Android:
viewModel.autoWired(json, extra, new SingleThreadExecutor.ExecuteCallback() {
            @Override
            public void onComplete() {
                System.out.println("json--->onComplete");
            }

            @Override
            public void onError(RuntimeException e) {
                System.out.println("json--->onError=" + e.getMessage());
            }
        });
  • iOS自动装配

    在ViewController.m中添加如下代码:

#import <MLNUIKit.h>
#import "ViewController.h"
#import "MovieData.h"

@interface ViewController ()

@property() MovieData *model;

@end

@implementation ViewController{
    NSDictionary *_origin;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // 1. 创建一个MLNUIViewController示例
    MLNUIViewController *viewController = [[MLNUIViewController alloc] initWithEntryFileName:@"chat_demo/VChatMovieList.lua" bundleName:@"MLNUIDemoTestMUI"];

    // 读取json数据
    _origin = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"MovieData.plist" ofType:nil]];
    self.model = [MovieData new];
    //调用autoWired方法,自动装配
    [self.model autoWired:_origin extra:nil complete:^(__kindof NSObject * _Nonnull model, NSError * _Nonnull error) {
        printf("装配完毕");
    }];
    [viewController bindData:self.model forKey:@"MovieData"];
    
    // 3.添加到指定的控制器上.
    [viewController mlnui_addToSuperViewController:self frame:self.view.bounds];

}
  • Android自动装配

    在Activity、Fragment或任意view中显示LuaView及Databingding使用

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //声明对象
        argo = new Argo(this);
        //是否打开debug按钮
        argo.showDebugButton(true);
        //ViewModel绑定,提供autoWired方法,将网络请求返回的json串自动解析作为`ViewModel`的默认数据。
        MovieDataViewModel viewModel = new MovieDataViewModel();

        String json = getJson(); 
        //传入网络请求后的json串 和 viewModel
        viewModel.autoWired(json, extra, new SingleThreadExecutor.ExecuteCallback() {
            @Override
            public void onComplete() {
                System.out.println("json--->onComplete");
            }

            @Override
            public void onError(RuntimeException e) {
                System.out.println("json--->onError=" + e.getMessage());
            }
        });
        argo.bind(viewModel);
    }
    //读取本地json
    public String getJson() {
        StringBuilder stringBuilder = new StringBuilder();

        try {
            Context context = getApplicationContext();
            AssetManager assetManager = context.getAssets();
            BufferedReader bf = new BufferedReader(new InputStreamReader(assetManager.open("MovieData.json")));
            String line;
            while ((line = bf.readLine()) != null) {
                stringBuilder.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return stringBuilder.toString();
    }
    @Override
    protected void onPause() {
        super.onPause();
        argo.onPause(); 
    }

    @Override
    protected void onResume() {
        super.onResume();
        argo.onResume(); 
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        argo.onDestroy(); 
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (argo.onActivityResult(requestCode, resultCode, data))
            return;
        super.onActivityResult(requestCode, resultCode, data);
    }

二、手动装配

简介:

编写demo.ag代码时,我们通常在preview中初始化数据源。打包之后将preview的数据源作为ViewModel的默认数据,即为手动装配。

用法:

1. ag声明式代码中,在preview里构造数据源

2. 打包

3. 打包之后生成的ViewModel提供defaultUserData方法将preview的数据源作为ViewModel的默认数据。

--关键代码如下:调用defaultUserData方法。
--iOS:
self.model = [MovieData defaultUserData];
--Android:
MovieDataViewModel viewModel = MovieDataViewModel.defaultUserData();
  • iOS手动装配

    在ViewController.m中添加如下代码:

#import <MLNUIKit.h>
#import "ViewController.h"
#import "MovieData.h"

@interface ViewController ()

@property() MovieData *model;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // 1. 创建一个MLNUIViewController示例
    MLNUIViewController *viewController = [[MLNUIViewController alloc] initWithEntryFileName:@"chat_demo/VChatMovieList.lua" bundleName:@"MLNUIDemoTestMUI"];

   //手动装配:ViewModel调用`defaultUserData`方法将`preview`的数据源作为`ViewModel`的默认数据。
    self.model = [MovieData defaultUserData];
    [viewController bindData:self.model forKey:@"MovieData"];
    
    // 3.添加到指定的控制器上.
    [viewController mlnui_addToSuperViewController:self frame:self.view.bounds];

}
  • Android手动装配

    在Activity、Fragment或任意view中显示LuaView及Databingding使用

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //声明对象
        argo = new Argo(this);
        //是否打开debug按钮
        argo.showDebugButton(true);
        //加载lua文件,已经合并到bind方法中
        //argo.loadAssetsUI("VChatMovieList.lua");
        //ViewModel绑定,提供defaultUserData方法,将argo源文件中的preview数据作为初始数据,即手动装配
        MovieDataViewModel viewModel = MovieDataViewModel.defaultUserData();
        argo.bind(viewModel); 
    }

    @Override
    protected void onPause() {
        super.onPause();
        argo.onPause(); 
    }

    @Override
    protected void onResume() {
        super.onResume();
        argo.onResume(); 
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        argo.onDestroy(); 
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (argo.onActivityResult(requestCode, resultCode, data))
            return;
        super.onActivityResult(requestCode, resultCode, data);
    }

附:

argo代码
model(MovieData)

WHITE = Color(0xffffff)

CellStyle = {
    tag = {
        padding(0, 5, 0, 5),
        height(15),
        cornerRadius(7.5),
        positionType(PositionType.ABSOLUTE),
        fontSize(9), top(3),
        textAlign(TextAlign.CENTER), textColor(Color(0x161616)),
        gradientColor(Color(0x24bce3), Color(0x5cd2c9), true)
    },
    title = {
        crossSelf(CrossAxis.CENTER),
        lines(2),
        fontSize(15),
        display(true),
        setLineSpacing(5)
    },
    share = {
        crossSelf(CrossAxis.CENTER),
        lines(1),
        basis(0),
        grow(1),
        textColor(Color(0x6e6e6e)),
        fontSize(12)
    },
    deleteBtn = {
        width(30),
        height(30),
        setImage("https://s.momocdn.com/w/u/others/custom/lua/vchat/movie/icon-delete.png", "https://s.momocdn.com/w/u/others/custom/lua/vchat/movie/icon-delete.png")
    },
    duration = {
        positionType(PositionType.ABSOLUTE),
        fontSize(10),
        textColor(WHITE),
        positionRight(7),
        positionBottom(5)
    }
}
TagColor = {
    ["电影"] = { from = Color(36, 188, 227), to = Color(92, 210, 201) },
    ["剧集"] = { from = Color(217, 194, 9), to = Color(226, 157, 7) },
    ["综艺"] = { from = Color(181, 142, 255), to = Color(251, 98, 250) },
    ["搞笑"] = { from = Color(116, 210, 67), to = Color(183, 223, 127) },
}
NavBar(mark_data(title)) {
    VStack().subs(
        ImageButton()
        .width(34)
        .height(34)
        .setImage("http://s.momocdn.com/w/u/others/custom/lua/vchat/movie/icon-back.png", "http://s.momocdn.com/w/u/others/custom/lua/vchat/movie/icon-back.png")
        .positionType(PositionType.ABSOLUTE)
        .left(10)
        .padding(5, 5, 5, 5)
        ,
        Label(title)
        .textColor(WHITE)
        .fontSize(16)
        .crossSelf(CrossAxis.CENTER)

    ).height(50).widthPercent(100).mainAxis(MainAxis.CENTER)
}

MovieCell(mark_data(item)) {
    HStack().subs(
        VStack().subs(
            ImageView(item.cover).contentMode(ContentMode.SCALE_ASPECT_FILL)
            .width(145).height(81.5).cornerRadius(6)
            ,
            Label().style(CellStyle.duration).text(item.isPlaying and "正在播放" or item.groupCount .. "个视频")
        )
        ,
        VStack().subs(
        -- 标签
            Label(item.tag).style(CellStyle.tag).ID(CellTag).watch(function()
                -- 标签颜色处理
                local clr = TagColor[item.tag] or TagColor["电影"]
                if clr then
                    CellTag.gradientColor(clr.from, clr.to, true)
                end
            end),
        -- title
            Label(item.title).style(CellStyle.title).textColor(item.isPlaying and Color(59, 179, 250) or WHITE)
            ,
            HStack().subs(
                Label(item.share).style(CellStyle.share),
                ImageButton().style(CellStyle.deleteBtn).padding(7, 7, 7, 7).display(item.showDeleteBtn)
            ).top(10).widthPercent(100)
        ).left(10).basis(0).grow(1)
    ).widthPercent(100).crossAxis(CrossAxis.CENTER)
    .padding(8, 10, 8, 10)
}
MovieListView(mark_data(listVM)) {
    List(listVM).bindCell(function(item)
        return MovieCell(item)
    end).top(2)
}
---
--- UI
ui {
    --- layout views
    VStack().subs(
        NavBar(MovieData.title)
        ,
        MovieListView(MovieData.list).basis(0).grow(1)
    ).widthPercent(100)
    .height(window.height() - 100)
    .cornerRadius(10, MBit.bor(RectCorner.TOP_LEFT, RectCorner.TOP_RIGHT))
    .bgColor(Color(0, 0, 0, 0.9))
    .positionType(PositionType.ABSOLUTE)
    .positionBottom(0)
}

---
--- preview
local function preview()
    --origin:网络请求获取的json数据
    --json串和ViewModel对应即可
    function autoWired(origin, viewModel, extra)
        viewModel = origin.data
        return viewModel
    end

    MovieData.title = "播放列表"
    MovieData.list = {
        {
            groupCount = 1, --//参数说明:合辑子视频总数 非必选
            cover = "http://s.momocdn.com/w/u/others/custom/lua/vchat/movie/tmp/3.png",
            tag = "电影",
            title = "           2020最期待的丧失电影-釜山行2【2020韩国动2020韩国动2020韩国动2020韩国动",
            share = "你还没有梦想 分享",
            showDeleteBtn = false,
            isPlaying = true,
        },
        {
            groupCount = 2, --//参数说明:合辑子视频总数 非必选
            cover = "http://s.momocdn.com/w/u/others/custom/lua/vchat/movie/tmp/3.png",
            tag = "剧集",
            title = "           2020最期待的丧失电影-釜山行2【2020韩国动2020韩国动2020韩国动2020韩国动",
            share = "你还没有梦想 分享",
            showDeleteBtn = false,
            isPlaying = false,
        },
        {
            groupCount = 1, --//参数说明:合辑子视频总数 非必选
            cover = "http://s.momocdn.com/w/u/others/custom/lua/vchat/movie/tmp/3.png",
            tag = "综艺",
            title = "           2020最期待的丧失电影-釜山行2【2020韩国动2020韩国动2020韩国动2020韩国动",
            share = "你还没有梦想 分享",
            showDeleteBtn = true,
            isPlaying = false,
        }
    }
end
json数据
{
  "code": 200,
  "data": {
    "title": "播放列表json",
    "list": [
      {
        "groupCount": 1,
        "cover": "http://s.momocdn.com/w/u/others/custom/lua/vchat/movie/tmp/3.png",
        "tag": "搞笑",
        "title": "           猫和老鼠 Jerry and Jerry and Jerry",
        "share": "你还没有梦想 快去分享吧",
        "showDeleteBtn": false,
        "isPlaying": true
      },
      {
        "groupCount": 1,
        "cover": "http://s.momocdn.com/w/u/others/custom/lua/vchat/movie/tmp/3.png",
        "tag": "电影",
        "title": "           猫和老鼠 Jerry and Jerry and Jerry",
        "share": "你还没有梦想 快去分享吧",
        "showDeleteBtn": true,
        "isPlaying": false
      },
      {
        "groupCount": 2,
        "cover": "http://s.momocdn.com/w/u/others/custom/lua/vchat/movie/tmp/3.png",
        "tag": "综艺",
        "title": "           猫和老鼠 Jerry and Jerry and Jerry",
        "share": "你还没有梦想 快去分享吧",
        "showDeleteBtn": false,
        "isPlaying": false
      },
      {
        "groupCount": 3,
        "cover": "http://s.momocdn.com/w/u/others/custom/lua/vchat/movie/tmp/3.png",
        "tag": "剧集",
        "title": "           猫和老鼠 Jerry and Jerry and Jerry",
        "share": "你还没有梦想 快去分享吧",
        "showDeleteBtn": false,
        "isPlaying": false
      },
      {
        "groupCount": 1,
        "cover": "http://s.momocdn.com/w/u/others/custom/lua/vchat/movie/tmp/3.png",
        "tag": "电影",
        "title": "           猫和老鼠 Jerry and Jerry and Jerry",
        "share": "你还没有梦想 快去分享吧",
        "showDeleteBtn": false,
        "isPlaying": false
      }
    ]
  }
}
plist数据
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>code</key>
	<integer>200</integer>
	<key>data</key>
	<dict>
		<key>list</key>
		<array>
			<dict>
				<key>cover</key>
				<string>http://s.momocdn.com/w/u/others/custom/lua/vchat/movie/tmp/3.png</string>
				<key>groupCount</key>
				<integer>1</integer>
				<key>isPlaying</key>
				<true/>
				<key>share</key>
				<string>你还没有梦想 快去分享吧</string>
				<key>showDeleteBtn</key>
				<false/>
				<key>tag</key>
				<string>搞笑</string>
				<key>title</key>
				<string>           猫和老鼠 Jerry and Jerry and Jerry</string>
			</dict>
			<dict>
				<key>cover</key>
				<string>http://s.momocdn.com/w/u/others/custom/lua/vchat/movie/tmp/3.png</string>
				<key>groupCount</key>
				<integer>1</integer>
				<key>isPlaying</key>
				<false/>
				<key>share</key>
				<string>你还没有梦想 快去分享吧</string>
				<key>showDeleteBtn</key>
				<true/>
				<key>tag</key>
				<string>电影</string>
				<key>title</key>
				<string>           猫和老鼠 Jerry and Jerry and Jerry</string>
			</dict>
			<dict>
				<key>cover</key>
				<string>http://s.momocdn.com/w/u/others/custom/lua/vchat/movie/tmp/3.png</string>
				<key>groupCount</key>
				<integer>2</integer>
				<key>isPlaying</key>
				<false/>
				<key>share</key>
				<string>你还没有梦想 快去分享吧</string>
				<key>showDeleteBtn</key>
				<false/>
				<key>tag</key>
				<string>综艺</string>
				<key>title</key>
				<string>           猫和老鼠 Jerry and Jerry and Jerry</string>
			</dict>
			<dict>
				<key>cover</key>
				<string>http://s.momocdn.com/w/u/others/custom/lua/vchat/movie/tmp/3.png</string>
				<key>groupCount</key>
				<integer>3</integer>
				<key>isPlaying</key>
				<false/>
				<key>share</key>
				<string>你还没有梦想 快去分享吧</string>
				<key>showDeleteBtn</key>
				<false/>
				<key>tag</key>
				<string>剧集</string>
				<key>title</key>
				<string>           猫和老鼠 Jerry and Jerry and Jerry</string>
			</dict>
			<dict>
				<key>cover</key>
				<string>http://s.momocdn.com/w/u/others/custom/lua/vchat/movie/tmp/3.png</string>
				<key>groupCount</key>
				<integer>1</integer>
				<key>isPlaying</key>
				<false/>
				<key>share</key>
				<string>你还没有梦想 快去分享吧</string>
				<key>showDeleteBtn</key>
				<false/>
				<key>tag</key>
				<string>电影</string>
				<key>title</key>
				<string>           猫和老鼠 Jerry and Jerry and Jerry</string>
			</dict>
		</array>
		<key>title</key>
		<string>播放列表json</string>
	</dict>
</dict>
</plist>
Clone this wiki locally