我有一段时间对此感到困惑.我正在RibbonWindow使用MVVM模式编写相当大的WPF应用程序.屏幕RibbonBar顶部有一个菜单,其余部分显示各种视图.某些视图包含其他视图,其中一些视图具有启动子窗口的按钮.
到目前为止,我一直在使用View代码隐藏文件执行此操作,但我知道在使用MVVM时这些文件应该是空的.我可以将子窗口启动代码移动到ViewModel,但是我需要一个对main的引用RibbonWindow(设置为子窗口所有者),这似乎不正确.
关于如何使用MVVM正常实现这一建议或提示将不胜感激.
通过 Viewmodel 中的 LiveData,我们可以像这样使用 switchMap 或 Transformations.map
val recipesList = cuisineType.switchMap { repository.getDisplayRecipes(it.cuisineType).asLiveData() }
Run Code Online (Sandbox Code Playgroud)
使用 StateFlow 实现此目的的最佳方法是什么?我知道我们可以像下面一样使用地图,但是这会返回 Flow<Flow<List<Recipe>>> ,这似乎不正确
val recipeListFlow = cuisineTypeStateFlow.map {
repository.getDisplayRecipes(it.cuisineType)
}
Run Code Online (Sandbox Code Playgroud) 我对查看模型比较新,我遇到了一些使用它们的问题.这是一种情况,我想知道最佳做法是什么......
我将视图所需的所有信息都放入视图模型中.这是一个例子 - 请原谅任何错误,这是我的头顶编码.
public ActionResult Edit(int id)
{
var project = ProjectService.GetProject(id);
if (project == null)
// Something about not found, possibly a redirect to 404.
var model = new ProjectEdit();
model.MapFrom(project); // Extension method using AutoMapper.
return View(model);
}
Run Code Online (Sandbox Code Playgroud)
如果屏幕只允许编辑一个或两个字段,当视图模型返回时,它会丢失相当多的数据(应该是这样).
[HttpPost]
public ActionResult Edit(int id, ProjectEdit model)
{
var project = ProjectService.GetProject(id);
if (project == null)
// Something about not found, possibly a redirect to 404.
try
{
if (!ModelState.IsValid)
return View(model) // Won't work, view model is …Run Code Online (Sandbox Code Playgroud) 我使用了一个非常标准且保存得很好的DDD模式继承了一个MVC2项目.我也在整个DTO/ViewModel辩论中做了很多阅读.
目前我们的DTO经常像ViewModels一样使用.它老实说并没有对我们正在做的事情产生影响,但我想在升级网站时使用正确的ViewModel.
这是我的问题:
我们的"域"项目模型目前拥有实体并将DTO返回给我的控制器.现在我需要将该DTO映射到ViewModel.我应该在哪里这样做?
我将ViewModel与我们的"Web"项目中的视图保持在一起,因此在域项目中转换DTO - > ViewModel感觉不对.在控制器中执行此操作也感觉不对.
其他人做了什么?
编辑:
这个问题/答案建议在控制器中处理它.很容易想到这一点.
asp.net-mvc domain-driven-design dto separation-of-concerns viewmodel
我使用EF4 DbContext为ASP.NET MVC应用程序提供模型.我使用ViewModels为视图和Automapper提供数据,以执行EF POCO和ViewModel之间的映射.Automapper做得很好,但在将ViewModel发回控制器进行更新后,我不清楚使用它的最佳方法.
我的想法是使用ViewModel中包含的密钥获取POCO对象.然后,我想使用Automapper使用ViewModel中的数据更新POCO:
[HttpPost]
public ActionResult Edit(PatientView viewModel)
{
Patient patient = db.Patients.Find(viewModel.Id);
patient = Mapper.Map<ViewModel, Patient>(viewModel, patient);
...
db.SaveChanges();
return RedirectToAction("Index");
}
Run Code Online (Sandbox Code Playgroud)
两个问题:
asp.net-mvc viewmodel automapper entity-framework-4 dbcontext
我试图在下面的代码中找到,为什么一旦我用新数据填充数据库,Room的LiveData observable就不会给我新的转变.
这是我的活动的onCreate方法:
shiftsViewModel = ViewModelProviders.of(this).get(ShiftsViewModel.class);
shiftsViewModel
.getShifts()
.observe(this, this::populateAdapter);
Run Code Online (Sandbox Code Playgroud)
这是populateAdapter方法:
private void populateAdapter(@NonNull final List<Shift> shifts){
recyclerView.setAdapter(new SimpleItemRecyclerViewAdapter(shifts));
}
Run Code Online (Sandbox Code Playgroud)
我还有以下代码填充数据库(我使用RxJava在IO线程上完成工作,因为Room需要在主线程之外调用它的代码):
@Override
public Observable<List<Shift>> persistShifts(@NonNull final List<Shift> shifts){
return Observable.fromCallable(() -> {
appDatabase.getShiftDao().insertAll(shifts);
return shifts;
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}
Run Code Online (Sandbox Code Playgroud)
在我开始观察我的shiftViewModel之后调用persistShifts时出现的问题.我希望我的观察者(LiveData)会被所有新添加的班次触发.事实证明,观察者被触发了,但是返回了一个空的移位列表.使其"工作"的唯一方法是,如果我离开活动(因此销毁当前的ViewModel)并再次输入.这次viewModel的LiveData为我提供了之前保持的所有变化,正如预期的那样.
这是代码的其余部分:
@Entity
public class Shift{
@PrimaryKey
private long id;
private String start;
private String end;
private String startLatitude;
private String startLongitude;
private String endLatitude;
private String endLongitude;
private String image;
...
Run Code Online (Sandbox Code Playgroud)
DAO:
@Dao
public interface ShiftDAO {
@Query("SELECT * FROM …Run Code Online (Sandbox Code Playgroud) android viewmodel android-room android-livedata android-architecture-components
这是土地的平原.像大多数人一样,我有我的域对象,我有我的视图模型.我喜欢使用视图模型的想法,因为它允许专门为给定的视图上下文创建模型,而无需更改我的业务对象.
我遇到的问题是在我的域对象上定义类型级别验证并将这些规则提供给客户端.在这种情况下,假设我使用数据注释来描述验证规则,当我将数据从域对象移动到视图模型时,视图模型不再知道应该让接口执行哪些验证(因为验证是定义回域对象).
使用MVC 2,您可以根据当前对象的验证规则自动执行客户端/服务器端验证.但是因为验证规则是在域对象而不是视图模型上定义的,所以我必须在视图模型上复制验证规则才能使其工作.
其他人如何处理这类问题?我的想法是,除了将数据从域对象映射到视图模型之外,我们还需要映射验证规则,但我还没有真正看到其他人谈论这个问题... Brad Wilson最近谈到了这个问题最后,但没有真正解决域对象和视图模型上的规则重复...你有什么想法?
干杯安东尼
可能重复:
ASP.NET MVC - Linq to Entities模型作为ViewModel - 这是一个好习惯吗?
可以使用EF实体类作为ASP.NET MVC中的视图模型吗?
如果viewmodel与EF实体类的90%相同怎么办?
假设我在Entity Framework模型中有一个Survey类.它90%匹配视图编辑所需的数据.与视图模型应该具有的唯一区别 - 是要在其中使用的一个或多个属性(填充Survey对象所需的因为EF类不能直接映射到它的属性的表示方式(子复选框,无线电组等) .))
你使用ViewData []传递它们吗?或者使用新的附加属性创建Survey类(SurveyViewModel)的副本(它应该能够从Survey复制数据并返回到它)?
编辑: 我也试图避免使用Survey作为SurveyViewModel属性.当使用UpdateModel或默认绑定器更新某些Survey属性时,看起来很奇怪,而其他(无法直接映射到实体) - 在控制器中使用SurveViewModel自定义属性.
我正在寻找一种在我的主窗口中调用方法的简单方法,但我想从我的View Model中调用它.基本上,我正在寻找一些"this.parent"之类的东西放在View Model中引用主窗口.
或者,如果你想查看我想要这样做的原因并告诉我另一种解决我的问题的方法:
我正在使用一个不断获取信息的应用程序.在viewmodel中,处理信息.我想在每次提供满足一定资格的信息时发出通知.
最初,我在viewmodel中有一个字典存储了有关该信息的信息,我在MainWindow中访问了该字典,以便我可以使窗口闪烁并发送其他通知.但是当我在MainWindow中访问它时,我遇到了viewmodel字典不断变化的问题.
对不起,这个问题听起来很愚蠢.我刚刚在两个月前开始使用WPF,并且在此之前也没有很好的编程背景.
我正在研究使用MVVM,虽然我在很大程度上理解它,但有一件事我无法理解.
想象一下,我有一个View和ViewModel组合,显示了一个foobars列表.当用户在列表中选择foobar并单击编辑按钮时,我希望foobar显示在弹出对话框窗口中,以便进行编辑.此对话窗口(视图)将具有自己的关联ViewModel.
我知道按钮可以绑定到ViewModel列表上的命令,但是从这里我如何实例化foobar编辑器?
1)我是否必须将消息发送回View,这将打开对话窗口?如果是这样,这不是打败了命令的目的吗?
2)如何将foobar传递给编辑器的ViewModel?如果它是由它的构造函数,这不是很难在XAML中声明ViewModel吗?
我觉得这是阻止我使用MVVM的最后一块拼图,我真的很想得到一个很好的解耦方案.
谢谢马特
viewmodel ×10
asp.net-mvc ×4
mvvm ×3
wpf ×3
android ×2
automapper ×2
c# ×2
android-architecture-components ×1
android-room ×1
childwindow ×1
dbcontext ×1
dto ×1
kotlin ×1
parameters ×1
validation ×1
view ×1