• Unity应用架构设计(5)——ViewModel之间如何共享数据


    对于客户端应用程序而言,单页应用程序(Single Page Application)是最常见的表现形式。有经验的开发人员往往会把一个View分解多个SubView。那么,如何在多个SubView之间 『共享数据』 是一个很棘手的事情。又因为ViewModel才是真正为View提供数据来源,所以本质上『共享数据』指的是多个ViewModel之间共享同一块数据控件。

    JavaScript中的原型链

    谈到『共享』两字,脑海里跳出第一个印象就是『继承』。对吧,因为你是父母的孩子,所以理所当然你可以和父母共享家中的一切。所以『共享』的前提,就是构建一个『继承链』,也就是JavaScript中的『原型链』。

    那么JavaScript是怎样实现原型链呢?有经验的JavaScript程序员想必早就记的滚瓜烂熟了——通过内置属性 __proto__ 来实现。

    所以ViewModel之间『共享数据』的核心就是如何去实现一个继承链,如下所示:

    为ViewModel构建继承关系

    有了上述的分析之后,只要仿照JavaScript的 __proto__ 的实现,我们对所有ViewModel的基类ViewModelBase添加一个ParentViewModel 属性,它代表当前ViewModel的父亲对象。

    public class ViewModelBase
    {
        public ViewModelBase ParentViewModel { get; set; }
    	//...
    }
    

    接着我参考了WPF中是怎样获取父ViewModel当中的数据:

     Binding="{Binding RelativeSource={RelativeSource FindAncestor, 
     AncestorType={x:Type Window}}, Path=DataContext.ParentViewModelProperty}
    

    可以看到通过 FindAncestor 方法,去指定 AncestorType 类型的上层对象中获取数据。

    所以,我为ViewModelBase 增加一个扩展方法,可以通过继承链实现从指定的祖先对象获取数据。

        public static IEnumerable<T> Ancestors<T>(this ViewModelBase origin) where T : ViewModelBase
        {
            if (origin==null)
            {
                yield break;
            }
            var parentViewModel = origin.ParentViewModel;
            while (parentViewModel!=null)
            {
                var castedViewModel = parentViewModel as T;
                if (castedViewModel != null)
                {
                    yield return castedViewModel;
                }
                parentViewModel = parentViewModel.ParentViewModel;
            }
    
        }
    

    对应在ViewModel中,可以通过 Ancestors扩展方法获取上层对象的数据

    var ancestors = this.Ancestors<FaceBoxViewModel>();
    

    最后,以图示的形式会更加直观,下图所示,SubViewModel依靠继承链可以轻松访问到ParentViewModel的共享数据:

    小结

    本篇文章介绍了怎样在ViewModel之间共享数据,实际上解决方案是非常简单的,人为的构造了一个继承链并随着继承链往上找,总是能找到希望获取到的数据。类似与JavaScript中的原型链,维护了一种至上而下的父子关系。
    源代码托管在Github上,点击此了解

  • 相关阅读:
    php iconv函数转换出错问题
    linux 上配置swoole
    Linux中查看某 个软件的安装路径
    mysql 5.0存储过程学习总结
    maven--私服的搭建(Nexus的使用)
    Linux的chattr与lsattr命令详解
    [转]Delphi 中 image 控件加载bmp、JPG、GIF、PNG等图片的办法
    [转]Delphi 中动态链接库(dll)的建立和使用
    Delphi PChar与String互转
    [转]Delphi 快捷键 让你更像高手!!
  • 原文地址:https://www.cnblogs.com/OceanEyes/p/sharing_data_between_viewmodels.html
Copyright © 2020-2023  润新知