当使用MVVM模式时,当Model
对象变得复杂时,即当它们包含非原始/非内置属性时,我会遇到麻烦。在我的特定实例中,我有一个ModelA
,其中包含ModelB
个对象的集合,这些对象本身包含ModelC
个对象的集合:
class ModelA
{
public string Name { get; set; }
public OberservableCollection<ModelB> Bs { get; set; }
}
class ModelB
{
public string Make { get; set; }
public ObservableCollection<ModelC> Cs { get; set; }
}
class ModelC
{
public string Brand{ get; set; }
}
我有一个ModelAViewModel
,允许访问ModelB Bs
属性的集合。在这种情况下,我没有为ViewModel
创建ModelB
。我使用ModelB
s设置了ModelC
和DataTemplate
个集合(以及各个实例)的样式:
<DataTemplate x:Key="modelATemplate">
<Grid Margin="5">
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
<ScrollViewer Grid.Row="2" VerticalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding Bs}" ItemTemplate="{StaticResource modelBTemplate}"/>
</ScrollViewer>
</Grid>
</DataTemplate>
<DataTemplate x:Key="modelBTemplate">
<Grid Margin="5" HorizontalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="{Binding Make}">
<ItemsControl Grid.Row="1" ItemsSource="{Binding Mode=OneWay, Path=Cs}"
ItemTemplate="{StaticResource ResourceKey=modelCTemplate}">
</ItemsControl>
</Grid>
</DataTemplate>
我被告知这不是MVVM的做事方式,而且每个实体,即ModelB
和ModelC
应该有自己的ViewModel
。我被告知要保留Model
类,但为他们创建ViewModel
。我无法想象这是如何发挥作用的。
如果我创建ModelBViewModel
:
public class ModelBViewModel
{
ModelB MyModelB { get; set; }
}
我有一个困境 - 我已在ModelB
课程中拥有ModelA
个实例,我现在在ModelB
中有其他ModelBViewModel
个实例。是否有必要在ModelB
内遍历原始ModelA
集合并创建ModelBViewModel
s,将MyModelB
属性设置为与ModelA
中的java.io.FileNotFoundException: C:\Users\sswain\.m2\repository\com\sun\xml\bind\jaxb-xjc\2.2.4-1\jaxb-api.jar (The system cannot find the file specified)
at java.util.zip.ZipFile.open(Native Method) ~[na:1.8.0_45]
at java.util.zip.ZipFile.<init>(ZipFile.java:220) ~[na:1.8.0_45]
at java.util.zip.ZipFile.<init>(ZipFile.java:150) ~[na:1.8.0_45]
at java.util.jar.JarFile.<init>(JarFile.java:166) ~[na:1.8.0_45]
at java.util.jar.JarFile.<init>(JarFile.java:130) ~[na:1.8.0_45]
at org.apache.tomcat.util.scan.JarFileUrlJar.<init>(JarFileUrlJar.java:60) ~[tomcat-embed-core-8.5.6.jar:8.5.6]
at org.apache.tomcat.util.scan.JarFactory.newInstance(JarFactory.java:48) ~[tomcat-embed-core-8.5.6.jar:8.5.6]
at org.apache.tomcat.util.scan.StandardJarScanner.process(StandardJarScanner.java:338) ~[tomcat-embed-core-8.5.6.jar:8.5.6]
at org.apache.tomcat.util.scan.StandardJarScanner.scan(StandardJarScanner.java:288) ~[tomcat-embed-core-8.5.6.jar:8.5.6]
at org.apache.jasper.servlet.TldScanner.scanJars(TldScanner.java:262) [tomcat-embed-jasper-8.5.6.jar:8.5.6]
at org.apache.jasper.servlet.TldScanner.scan(TldScanner.java:104) [tomcat-embed-jasper-8.5.6.jar:8.5.6]
at org.apache.jasper.servlet.JasperInitializer.onStartup(JasperInitializer.java:101) [tomcat-embed-jasper-8.5.6.jar:8.5.6]
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5178) [tomcat-embed-core-8.5.6.jar:8.5.6]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) [tomcat-embed-core-8.5.6.jar:8.5.6]
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1403) [tomcat-embed-core-8.5.6.jar:8.5.6]
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1393) [tomcat-embed-core-8.5.6.jar:8.5.6]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_45]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_45]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_45]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_45]
属性相匹配?什么应该相当简单似乎有点复杂?
答案 0 :(得分:1)
MVVM意味着&#34;模型视图ViewModel&#34;。如您所见,该名称包含Model和ViewModel。我们的想法是为您拥有的每个Model类都有一个专用的ViewModel类。
ViewModel应包含特定于视图的属性和逻辑,而Model类应包含业务模型特定属性和逻辑。
并且:是的,对于一些非常简单的MVVM示例,这可能是开销。但是,只要您的视图逻辑开始偏离业务逻辑,您就会从这个分离中受益。
如果有必要迭代原始属性:我会说:是的! 我通常这样做:
public class ModelBViewModel
{
private ModelB _model;
public ObservableCollection<ModelCViewModel> CVms { get; set; }
public ModelBViewModel(ModelB model) {
_model = model;
CVms = new ObservableCollection();
foreach(var modelC in model.Cs) {
CVms.Add(new ModelCViewModel(modelC));
}
}
}