MvvmCross 框架中 ViewModel 之间的导航以及生命周期
MvvmCross 框架中 ViewModel 之间的导航以及生命周期
介绍 MvvmCross (Mvx) 框架中的 ViewModel 之间的导航以及 ViewModel 的生命周期。
在 ViewModel 之间导航
Mvx 框架中, 用一个页面跳转到另一个页面, 对应的也会从一个 ViewModel 跳转到另外的 ViewModel , 页面间的跳转由 ViewModel 发起, 通常会调用 ShowViewModel
方法来完成 ViewModel 之间的导航, 这个方法提供了一下几个重载版本:
protected bool ShowViewModel<TViewModel>(
IMvxBundle parameterBundle = null,
MvxBundle presentationBundle = null,
MvxRequestedBy requestedBy = null
) where TViewModel : IMvxViewModel { ... };
这个重载版本所有的参数的默认值都是 null
, 可以不提供任何参数。
protected bool ShowViewModel<TViewModel>(
object parameterValuesObject,
MvxBundle presentationBundle = null,
MvxRequestedBy requestedBy = null
) where TViewModel : IMvxViewModel { ... };
这个重载版本需要提供一个类型为 object
的对象, 通常会使用匿名对象或者一个复杂类型对象, 其它参数为可选。
protected bool ShowViewModel<TViewModel>(
IDictionary<string, string> parameterValues,
MvxBundle presentationBundle = null,
MvxRequestedBy requestedBy = null
) where TViewModel : IMvxViewModel { ... };
这是使用字典参数的重载版本, 可以传入一个 Key 和 Value 均为字符串的字典。
当然, 还有一些非泛型的版本没有列出来, 值得一提的是, 虽然有这么多重载版本的导航函数, 在项目中推荐使用统一一种风格的版本。
ViewModel 的生命周期
基于依赖注入的创建 (Construct)
Mvx 提供了一个依赖注入容器, 它在初始化 ViewModel 时就使用了依赖注入, 比如 ViewModel 的构造函数是这样的:
public MyViewModel(IEmailService service) { ... }
如果 IEmailService
已经在 Mvx 容器中注册过了, IEmailService
对应的实例就会自动注入给 MyViewModel
, 如果在程序中需要手工初始化一个对象, 也可以通过 Mvx.IocConstruct<T>()
方法来初始化指定的 ViewModel 。
构造函数与不使用上面
ShowViewModel
方法中传递的参数, 参数会传递给下面要介绍的 Init 方法。
基于约定的初始化 (Init)
ViewModel 的构造函数执行完成之后, Mvx 接下来会调用 ViewModel 的 Init
方法, 这个方法接收 ShowViewModel
传递的参数, Init
方法的参数可以有以下几种形式:
多个简单类型的参数
使用多个简单类型的参数, 签名如下所示:
public void Init(int a, string b, float c)
要调用这种签名类型的参数, 需要在 ShowViewModel 方法的参数中使用匿名类 (anonymous class) , 并且匿名类的属性名称必须和 Init 函数的各个参数名称相同。
一个复杂类型的参数
Init 方法还可以使用一个复杂类型的参数, 并且只能有一个参数, 参数的成员只能包含简单类型, 如下所示:
public void Init(Parameter param)
要调用这种类型的参数, 需要在 ShowViewModel 方法的参数中使用对应类型的实例。
使用 IMvxBundle 参数
如果上面的两种形式都不能满足需要, 则还可以使用 IMvxBundle 参数, 如下所示:
public void init(IMvxBundle)
IMvxBundle 是 Mvx 提供的类型, 类似于字典, 可以自己读写需要的类型, 要调用到这个方法, 需要在 ShowViewModel 方法中提供 IMvxBundle 的实例, 不过很少用到这种类型的 Init 方法。
上面的三种形式的 Init 方法可以同时出现在一个 ViewModel 中, 不过推荐的是在一个应用中只是用一种风格的 Init 方法。
简单类型是指是指 int , long , double , string , Guid, enum 。
ReloadState
如果 ViewModel 是从墓碑状态中恢复的, 将会调用 ReloadState 方法, 否则不会调用这个方法。 这个方法支持的参数形式和 Init 相同, 一般 Mvx 期待的形式如下所示:
public class DetailViewModel : MvxViewModel {
// ...
public class SavedState {
public string Name {get;set;}
public int Position {get;set;}
}
public void ReloadState(SavedState savedState) {
// use savedState
}
// ...
}
既然有 ReloadState , 就肯定会有 SaveState , SaveState 也有两种实现形式:
使用无参数的方法返回强类型的对象
public class DetailViewModel : MvxViewModel {
public class SavedState {
public string Name {get;set;}
public int Position {get;set;}
}
public SavedState SaveState() {
return new SavedState() {
Name = _name,
Position = _position
};
}
}
重写 SavedStateToBundle(IMvxBundle bundle)
方法
public class DetailViewModel : MvxViewModel {
protected override void SaveStateToBundle(IMvxBundle bundle) {
bundle.Data["Name"] = _name;
bundle.Data["Position"] = _position.ToString();
}
}
Start
调用完 Construction
、 Init
和 ReloadState
之后, 会调用 ViewModel 的 Start 方法, 如下所示:
public class DetailViewModel : MvxViewModel {
// ...
public override void Start() {
// do any start
}
// ...
}
在安卓系统下使用了
MvxFragment
可以在Fragment
的OnStart
方法中调用 ViewModel 的Start
方法。
- Reactive Extensions介绍
- Reactive Extensions(Rx) 学习
- 发布一个日期选择控件(ASPNET2.0)
- 做程序员压力山大,很多人都快疯了
- 小程序让交通出行变得如此简化,看看这些微信小程序你有在用了吗?
- 中小企业如何选择DDoS防御方案?
- “熊医生”出诊正确率超九成 医院:人工智能更多是辅助
- PLC编程优化方法,让程序运行提速!
- 这是硅谷狂人马斯克对未来做出的11个大胆预测,人工智能比核武器更危险
- 在腾讯云上使用自建DNS
- Spring 4.0.2 学习笔记(1) - 最基本的注入
- 关于女神SQLite的疑惑(2)
- WordPress纯代码仿无觅相关文章图文模式功能(增强版)
- 人工智能时代已悄然来临……
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- php快速导入大量数据的实例方法
- Laravel 模型关联基础教程详解
- yunBT:一个基于TP3.1的多用户BT离线下载程序,支持在线播放
- 使用Chihaya搭建一个可以屏蔽迅雷的Tracker
- [jio本]Debian9一键安装各种下载工具
- php实现QQ小程序发送模板消息功能
- 微软自家沙盒 Sandbox公布
- php DES加密算法实例分析
- php提供实现反射的方法和实例代码
- PHP实现批量修改文件名的方法示例
- Linux VPS快速下载Bilibili视频脚本 ,支持1080P/720P/360P等格式
- PHP递归统计系统中代码行数
- PHP切割整数工具类似微信红包金额分配的思路详解
- php写入文件不覆盖的实例讲解
- php解决crontab定时任务不能写入文件问题的方法分析