Apache flex MVVM-什么应该包含什么。。。什么应该创造什么

Apache flex MVVM-什么应该包含什么。。。什么应该创造什么,apache-flex,silverlight,design-patterns,mvvm,Apache Flex,Silverlight,Design Patterns,Mvvm,我有一个正确的想法,即如何使用MVVM模式将所有内容组合在一起。在实践中,这一切似乎都很简单,但为了实现它,我似乎违反了我试图编写代码所依据的各种其他规则 作为旁注,我正在尝试使用Flex实现该模式,而不是Silverlight或WPF,因此,如果有人能提出不应该这样做的充分理由,那么我很乐意听取他们的意见 我有一个问题,我有几个观点。有时我不得不在页面上同时显示两个视图;有时我会切换回单一视图。在我正常的Flex大脑中,我会有一个包含代码的主视图,它包含了我所有的其他视图(与代码后面的视图相同

我有一个正确的想法,即如何使用MVVM模式将所有内容组合在一起。在实践中,这一切似乎都很简单,但为了实现它,我似乎违反了我试图编写代码所依据的各种其他规则

作为旁注,我正在尝试使用Flex实现该模式,而不是Silverlight或WPF,因此,如果有人能提出不应该这样做的充分理由,那么我很乐意听取他们的意见

我有一个问题,我有几个观点。有时我不得不在页面上同时显示两个视图;有时我会切换回单一视图。在我正常的Flex大脑中,我会有一个包含代码的主视图,它包含了我所有的其他视图(与代码后面的视图相同)。然后,该主视图将切换其他单个视图

当我试图在MVVM中实现这一点时,我试图通过使用绑定来坚持MVVM的原则,绑定将我的
视图
视图模型
分离。假设我为应用程序范围的状态创建了一个
ViewModel
,我的
ApplicationView
绑定到该数据,并执行子视图的所有切换

现在,我应该在哪里为我的子视图创建视图模型?我在
应用程序视图
中进行了尝试——这似乎不正确。然后我尝试在应用程序视图之外,将其和实例传递到
ApplicationView
中,然后我的子模型绑定到它。我错过什么了吗?这些方法似乎都不适合尝试将其解耦的全部要点

任何解释这个问题的好书或链接都将不胜感激

干杯,
James

我在两个不同的Flex项目中看到了MVVM方法的变体,但我还没有看到一种对我来说完全合适的方法。也就是说,我认为使用表示模型可以使Flex中的测试变得更加容易,所以我非常确信,将有更多的应用程序围绕这种模式设计

我见过的在Flex中实现MVVM的最简单方法是将单个的
ViewModel
s放在应用程序
Model
/
ModelLoactor
中。
ModelLoactor
包含任何全局数据,还充当所有
ViewModels
的访问器<代码>应用程序视图可以通过
模型定位器
绑定到其特定的
视图模型
,而
视图模型
可以通过命令和绑定到其父级
模型定位器
进行更新。这种方法的一个好处是所有的数据逻辑都是本地化的;当然,这也可能被视为一个缺点,因为中央
ModelLocator
由于其对所有
ViewModels
的硬编码引用而变得脆弱

我见过更干净的方法通过使用Mate框架工作。Mate允许将
视图模型
更分散地注入到相应的
应用程序视图
。(我想这也可以通过Swiz实现,我只是不太熟悉这个框架)。使用Mate,每个
ApplicationView
都通过映射注入了其
ViewModel
。这种方法最酷的地方在于如何使用EventMap(FrontController的Mate版本)更新
ViewModels
。本质上,您的
应用程序视图
将调度由一个或多个
事件映射
处理的事件,然后这些映射可以对一个或多个
视图模型
进行更改。这种方法允许一个
ApplicationView
中的用户手势或事件同时更改多个
ViewModels
的状态。此外,由于此逻辑被提取到Mate的
EventMaps
,因此很容易更改事件的处理方式或更改哪些
ViewModels
。当然,这种方法的主要缺点是您承诺使用Mate作为框架,这可能不是一个选项,这取决于项目的需求


我希望这有帮助

您所指的方法是ViewModel合成。在这里,您有多个复杂的视图零件需要绑定到它们自己的ViewModel实体。该方法需要构造一个根ViewModel,其中包含每个子ViewModel的属性。然后根视图绑定到根视图模型,每个视图(无论是显示的还是折叠的)绑定到根视图模型上的相应属性

ViewModel将如下所示:

public class RootViewModel 
{
   ChildViewModelA ChildA { get; set; }
   ChildViewModelB ChildB { get; set; }
}
<Grid>
   <ChildViewA DataContext="{Binding ChildA}" />
   <ChildViewB DataContext="{Binding ChildB}" />
</Grid>
public class RootViewModel 
{
   public List<ViewModel> ChildWorkspaces { get; set; }
   public ViewModel ActiveWorkspace { get; set; }

   public RootViewModel() 
   {
      ChildWorkspaces.Add(ChildViewModelA);
      ChildWorkspaces.Add(ChildViewModelB);
   }
}
<Grid>
   <Grid.Resources>
      <DataTemplate DataType="ChildViewModelA">
          <ChildViewA />
      </DataTemplate>
      <DataTemplate DataType="ChildViewModelB">
          <ChildViewB />
      </DataTemplate>
   </Grid.Resources>
   <ContentControl Content="{Binding ActiveWorkspace}" />
</Grid>
视图如下所示:

public class RootViewModel 
{
   ChildViewModelA ChildA { get; set; }
   ChildViewModelB ChildB { get; set; }
}
<Grid>
   <ChildViewA DataContext="{Binding ChildA}" />
   <ChildViewB DataContext="{Binding ChildB}" />
</Grid>
public class RootViewModel 
{
   public List<ViewModel> ChildWorkspaces { get; set; }
   public ViewModel ActiveWorkspace { get; set; }

   public RootViewModel() 
   {
      ChildWorkspaces.Add(ChildViewModelA);
      ChildWorkspaces.Add(ChildViewModelB);
   }
}
<Grid>
   <Grid.Resources>
      <DataTemplate DataType="ChildViewModelA">
          <ChildViewA />
      </DataTemplate>
      <DataTemplate DataType="ChildViewModelB">
          <ChildViewB />
      </DataTemplate>
   </Grid.Resources>
   <ContentControl Content="{Binding ActiveWorkspace}" />
</Grid>

您还可以在其他地方实现这一点,以允许自己选择一个活动的工作区

ViewModel将如下所示:

public class RootViewModel 
{
   ChildViewModelA ChildA { get; set; }
   ChildViewModelB ChildB { get; set; }
}
<Grid>
   <ChildViewA DataContext="{Binding ChildA}" />
   <ChildViewB DataContext="{Binding ChildB}" />
</Grid>
public class RootViewModel 
{
   public List<ViewModel> ChildWorkspaces { get; set; }
   public ViewModel ActiveWorkspace { get; set; }

   public RootViewModel() 
   {
      ChildWorkspaces.Add(ChildViewModelA);
      ChildWorkspaces.Add(ChildViewModelB);
   }
}
<Grid>
   <Grid.Resources>
      <DataTemplate DataType="ChildViewModelA">
          <ChildViewA />
      </DataTemplate>
      <DataTemplate DataType="ChildViewModelB">
          <ChildViewB />
      </DataTemplate>
   </Grid.Resources>
   <ContentControl Content="{Binding ActiveWorkspace}" />
</Grid>
公共类RootViewModel
{
公共列表子工作区{get;set;}
公共ViewModel ActiveWorkspace{get;set;}
公共RootViewModel()
{
添加(ChildViewModelA);
添加(ChildViewModelB);
}
}
视图如下所示:

public class RootViewModel 
{
   ChildViewModelA ChildA { get; set; }
   ChildViewModelB ChildB { get; set; }
}
<Grid>
   <ChildViewA DataContext="{Binding ChildA}" />
   <ChildViewB DataContext="{Binding ChildB}" />
</Grid>
public class RootViewModel 
{
   public List<ViewModel> ChildWorkspaces { get; set; }
   public ViewModel ActiveWorkspace { get; set; }

   public RootViewModel() 
   {
      ChildWorkspaces.Add(ChildViewModelA);
      ChildWorkspaces.Add(ChildViewModelB);
   }
}
<Grid>
   <Grid.Resources>
      <DataTemplate DataType="ChildViewModelA">
          <ChildViewA />
      </DataTemplate>
      <DataTemplate DataType="ChildViewModelB">
          <ChildViewB />
      </DataTemplate>
   </Grid.Resources>
   <ContentControl Content="{Binding ActiveWorkspace}" />
</Grid>

这将导致根据存储在ActiveWorkspace中的实际对象的类型隐式选择适当的视觉表示

对不起,我的回答是WPF。我尽了最大的努力不被它的语法所迷惑:-)

正如您所见,多个“ViewModel”可能不明确。我们经常发现需要构造多个子实体来适当地构造ViewModel。但所有ViewModel实体都将位于根视图模型对象中的某个位置

在WPF中实现MVVM时,我更喜欢推断隐式应用数据上下文的可视元素(如本响应后半部分所示)。在更复杂的场景中,我更喜欢使用DataTemplateSelector来进行决策。但在非常简单的情况下,你可以