我不确定将数据存储在WPF应用程序中的何处。有两个原则可能会发生冲突。有人可以解决这个问题吗?
原则1:数据应存储在模型中
接下来,例如,ObservableCollection<string> Articles
应存储在模型中。 ViewModel中的Property可以使其可用于View。
原则2:依赖于View的状态应存储在ViewModel中
这意味着具有相应属性string _SelectedArticle
的{{1}}变量应存储在ViewModel中。
到目前为止,我只将不影响View的方法或值放入模型中,因为我(也许)强烈遵循原则2.但我不确定这是否是正确的方法。< / p>
我是否应该在模型中保留一些数据,在ViewModel中保存一些数据,还是存放所有数据?
答案 0 :(得分:4)
简单的答案是:数据应该存储在它所属的位置。
在您的情况下,模型应该有:app:mergeDebugResources FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:mergeDebugResources'.
> Error: com.google.common.util.concurrent.UncheckedExecutionException: java.lang.RuntimeException: com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 1
* Try:
Run with --info or --debug option to get more log output.
* Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:mergeDebugResources'.
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:69)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:46)
at org.gradle.api.internal.tasks.execution.PostExecutionAnalysisTaskExecuter.execute(PostExecutionAnalysisTaskExecuter.java:35)
at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:64)
at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:58)
at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:42)
at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:52)
at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:53)
at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)
at org.gradle.api.internal.AbstractTask.executeWithoutThrowingTaskFailure(AbstractTask.java:310)
at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.executeTask(AbstractTaskPlanExecutor.java:79)
at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.processTask(AbstractTaskPlanExecutor.java:63)
at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.run(AbstractTaskPlanExecutor.java:51)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:54)
at org.gradle.internal.concurrent.StoppableExecutorImpl$1.run(StoppableExecutorImpl.java:40)
Caused by: com.android.build.gradle.tasks.ResourceException: Error: com.google.common.util.concurrent.UncheckedExecutionException: java.lang.RuntimeException: com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 1
at com.android.build.gradle.tasks.MergeResources.doFullTaskAction(MergeResources.java:164)
at com.android.build.gradle.internal.tasks.IncrementalTask.taskAction(IncrementalTask.java:104)
at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:75)
at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$IncrementalTaskAction.doExecute(AnnotationProcessingTaskFactory.java:243)
at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:219)
at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$IncrementalTaskAction.execute(AnnotationProcessingTaskFactory.java:230)
at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:208)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:80)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:61)
... 14 more
Caused by: Error: com.google.common.util.concurrent.UncheckedExecutionException: java.lang.RuntimeException: com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 1
at com.android.ide.common.res2.MergeWriter.end(MergeWriter.java:54)
at com.android.ide.common.res2.MergedResourceWriter.end(MergedResourceWriter.java:129)
at com.android.ide.common.res2.DataMerger.mergeData(DataMerger.java:291)
at com.android.ide.common.res2.ResourceMerger.mergeData(ResourceMerger.java:48)
at com.android.build.gradle.tasks.MergeResources.doFullTaskAction(MergeResources.java:157)
... 22 more
Caused by: java.lang.RuntimeException: com.google.common.util.concurrent.UncheckedExecutionException: java.lang.RuntimeException: com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 1
at com.android.ide.common.internal.WaitableExecutor.waitForTasksWithQuickFail(WaitableExecutor.java:117)
at com.android.ide.common.res2.MergeWriter.end(MergeWriter.java:50)
... 26 more
Caused by: com.google.common.util.concurrent.UncheckedExecutionException: java.lang.RuntimeException: com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 1
at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2201)
at com.google.common.cache.LocalCache.get(LocalCache.java:3934)
at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:3938)
at com.google.common.cache.LocalCache$LocalLoadingCache.get(LocalCache.java:4821)
at com.android.ide.common.blame.MergingLog.getWholeFileMap(MergingLog.java:128)
at com.android.ide.common.blame.MergingLog.logCopy(MergingLog.java:88)
at com.android.ide.common.blame.MergingLog.logCopy(MergingLog.java:98)
at com.android.ide.common.res2.MergedResourceWriter$1.call(MergedResourceWriter.java:215)
at com.android.ide.common.res2.MergedResourceWriter$1.call(MergedResourceWriter.java:171)
Caused by: java.lang.RuntimeException: com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 1
at com.android.ide.common.blame.MergingLogPersistUtil.loadFromSingleFile(MergingLogPersistUtil.java:293)
at com.android.ide.common.blame.MergingLog$1.load(MergingLog.java:55)
at com.android.ide.common.blame.MergingLog$1.load(MergingLog.java:52)
at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3524)
at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2317)
at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2280)
at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2195)
... 8 more
Caused by: com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 1
at com.google.gson.stream.JsonReader.syntaxError(JsonReader.java:1505)
at com.google.gson.stream.JsonReader.checkLenient(JsonReader.java:1386)
at com.google.gson.stream.JsonReader.doPeek(JsonReader.java:572)
at com.google.gson.stream.JsonReader.beginArray(JsonReader.java:332)
at com.android.ide.common.blame.MergingLogPersistUtil.loadFromSingleFile(MergingLogPersistUtil.java:266)
... 14 more
BUILD FAILED
。 ViewModel将使用此列表并在构造函数中构建List<string> Articles
。 ObservableCollection<string> Articles
也应存储在ViewModel中,如果其值仅用于在View中导航,并且永远不会在模型中使用或保存到数据访问层中的某个位置。
答案 1 :(得分:1)
模型应该包含需要保存的所有数据,例如,模型包含名字,姓氏,出生日期等的人物对象。
viewmodel然后包装此模型并应用在View和模型之间传递数据所需的任何逻辑,因此如果您想要Age字段,那么您不会在模型中保存年龄,而是指示视图模型计算它从DOB传递到视图,同样的业务规则,如输入验证发生在View模型级别,所以如果你的人必须超过18岁,你需要检查出生日期,然后再将其传递给模型进行保存,您还可以使用视图模型进行更改跟踪,因此如果您更改名字,则视图模型会引发属性更改事件而不是模型
然后视图控制如何显示数据,因此指示哪些控件链接到ViewModel中的哪些属性
大多数可选择的控件将其选定值定义为功能的一部分,因此如果您希望控件A显示在控件B中选择的内容,则将控件A绑定到控件B的所选项属性
在您的情况下,我希望看到一个控制数据库访问或Web服务等的文章模型
显示文章文本的ArticlesEditor ViewModel允许使用Save和cancel方法更改它,该方法可以从模型重新加载原始文本或将更改的文本复制到模型
然后是一个ArticlesList视图模型,其中包含一个可观察的ArticlesEditor集合,并包含创建和删除文章的方法
然后在你的视图中你将有一个listview绑定到ArticlesList.Articles属性,你的编辑器控件绑定了ListViews.SelectedItem属性,然后编辑器控件的控件将被绑定到ArticlesEditor对象的属性
答案 2 :(得分:0)
View 可见的所有数据都应存储在 ViewModel 中。 只需使用调用业务逻辑的viewmodel。 如果您的实体未映射到视图(如果您显示某些内容),则应使用模型,而不是其视图模型。