JavaScript中的原型链

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

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

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

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

为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的共享数据:

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

https://mp.weixin.qq.com/s/75JgBOAVbjJ68mb-2QNkBA