使用视图模型中的属性值实现方法的最佳实践是啥?

Posted

技术标签:

【中文标题】使用视图模型中的属性值实现方法的最佳实践是啥?【英文标题】:What is the best practice to implement methods using values of properties in the View Model?使用视图模型中的属性值实现方法的最佳实践是什么? 【发布时间】:2021-10-09 10:28:17 【问题描述】:

我目前正在开发一个 UWP 应用程序,但我认为这个问题适用于任何具有 UI 的项目类型。我使用新的 Microsoft Toolkit MVVM 库为我的 UI 构建了一个视图模型。它具有以下属性:

        private bool _isLoginAvailable = true;     
        public bool IsLoginAvailable
        
            get => _isLoginAvailable;
            set => SetProperty(ref _isLoginAvailable, value);
        

此外,我有一些业务方法作为参数需要多达 5-6 个这些属性。

在论坛上阅读,我发现视图模型中的业务逻辑不建议使用,因此,我提出了以下选项:

    为方法创建一个新类,并使用视图模型作为参数:SampleMethod(SampleViewModel vm)。然后,如果我在视图模型中创建此类的对象,我可以使用SampleMethod(this)。在这一点上,我真的看不出这个选项和在视图模型类中包含方法之间有什么区别。 我看到的第二个选项是将每个必需的参数添加到方法中,并在一个元组中返回每个参数:SampleMethod(var1, var2, var3...) return (var1, var2, var3...) 这对我来说似乎很麻烦。 我想到的第三个选项是使用 MVVM Toolkit 的消息传递功能。在这种情况下,我可以设置视图模型的构造函数来监听带有 Messenger.Register<SampleViewModel, Var1Message>(this, (r, m) => r.var1 = m.Value); 的消息。然后,不同类中的方法可以使用Messenger.Send(new Var1Message(message) 发送消息中的值。虽然这似乎是最好的选择,因为它可以与依赖注入一起轻松实现,但很快就会变得非常复杂,因为每个属性都需要一个新的密封类来描述消息。

这些选项中的任何一个是最佳做法,还是有我不知道的选项?

【问题讨论】:

“我看到不建议在视图模型中包含方法”。诶?作为一个没有意义的独立声明。 VM 可以包含任意数量的方法。你的意思是他们不应该包含 business 逻辑方法而不是视图逻辑? 您能否提供一个来源,说明为什么不建议在视图模型中包含方法? 将业务逻辑放在哪里是设计决策。有些人将控制器实例添加到 M-V-VM,有些人将所有逻辑放在 VM 中。一些模型。有些有一个额外的 BL 层。这是你自己的选择。 如果该方法适用于 VM 的属性,则无需传递任何内容。我会将方法留在拥有您使用的方法的同一 VM 类中。如果您将所有状态复制到下一个 VM 只是为了将方法与属性分开,那么您得到的只是代码膨胀。 @GazTheDestroyer,确实,我的意思是业务逻辑。 【参考方案1】:

如果业务方法需要 VM 中的多个属性,那么这些属性是否应该在业务对象中?这些属性是业务规则固有的,还是仅存在于视图的上下文中?

VM 属性可以直接传递给业务属性,或者您通常可以直接在 VM 中公开业务对象本身。

【讨论】:

这很有意义。实际上,即使这些属性也存在于 UI 上,它们主要与业务逻辑相关,因此它们应该在该类中。那么,在视图模型中,get 和 set 访问器可以用来访问业务逻辑中的属性,对吧? @BalazsSzekeres 完全正确。【参考方案2】:

为什么您认为在 ViewModel 中使用方法是不可取的?

ViewModel 必须充当 View、Model 和业务逻辑类或库之间的中介。

考虑在 ViewModel 中使用 RelayCommand(将属性实现为 ICommand 类型),这可以绑定到按钮单击并用于调用 ViewModel 中的方法,该方法获取属性值并将它们传递给您的业务逻辑。

ViewModel 的典型场景可能是用户在表单上输入,而您的 ViewModel 属性受视图绑定。然后用户单击一个按钮来提交此数据。

【讨论】:

RelayCommand 已经在我的视图模型中实现。 “制作一个获取属性值并将它们传递给您的业务逻辑的方法”,听起来类似于我在选项 2 中提到的内容。这是您的意思,还是我误解了? 不像您所说的返回元组值,这意味着所有属性值都是单独的项目。 MVVM Toolkit SetProperty 很麻烦,因为它需要一个单独的字段值,即使该值本身来自多属性模型类。然后将模型传递给业务逻辑。我不喜欢在我的 ViewModel 中嵌入业务逻辑,因为这样更容易进行单元测试和模拟(业务逻辑和 ViewModel)。

以上是关于使用视图模型中的属性值实现方法的最佳实践是啥?的主要内容,如果未能解决你的问题,请参考以下文章

通过视图模型接收 DateTime 输入的最佳实践是啥?

Yii2 - 获取所有唯一模型属性值的最佳方法是啥?

iOS - 为帖子 + 评论数据模型设置视图控制器的最佳实践是啥?

Android onClickListener实现最佳实践

根据 SQL Server 中的最新日期创建具有过滤值的新视图的最佳方法是啥?

在 Rails 中测试模型的最佳实践是啥?