目前正在进行一个项目,我正在尽最大努力避免剃刀文件上代码块中的任何C#,因此我正在努力遵循MVVM设计模式。我有一个测试视图模型,它只是试图从标记标记中获得一个字符串值。
ViewModel
public class MyViewModel : NotifiableAndDisposableBase
{
[Parameter]
public string Text { get; set; }
}
MyCard组件
@inject MyViewModel vm
<h3 style="color: white">MyCard</h3>
<h3 style="color: white">@vm.Text</h3>
查看
<div>
<MyCard Text="This is passed in"/>
</div>
现在,此代码将不起作用Text参数将不会在标记调用中被识别。我可以识别和传递参数的唯一方法是使用类似的@Code块
@code{
[Parameter]
public string CodeBlockText {get; set;}
}
或
我的组件没有使用[Inpject]my viewmodel,而是使用[Iinherits]my viewmodel,但使用Inherits意味着我必须使用Default构造函数,但我需要使用在StartUp.cs 中创建的持久HttpClient
我认为解决办法是在代码块中创建一个参数,然后在视图模型中设置实际属性,但我不确定这是否是一个好的做法。
如有任何建议,我们将不胜感激。
注入不是这样工作的。您需要在Program.cs
中设置提供程序。
类似builder.Services.AddScoped<MyViewModel>();
MVVM上下文中的组件是什么?这是视图的一部分。视图应该为您提供可以绑定ViewModel的属性。因此,在视图模型中不需要任何特定于运动夹克的声明。
MyViewModel
public class MyViewModel : NotifiableAndDisposableBase
{
public string Text { get; set; }
}
夸张地说,如果您有WPF的经验,那么无论WPF的Blazor如何,您都应该能够重用相同的ViewModel类
假设组件的工作是显示ViewModel,那么创建一个接受ViewModel实例的Parameter。我不会在组件中注入ViewModel,因为可能有几种不同的方法来创建这个ViewModel实例。它可以从服务加载。它可以在您开始编辑时创建。因此,如果有一个非常特殊的目的,我们会创建一个组件:显示ViewModel。这个组件不应该关心实例来自哪里。
MyViewModelDisplayComponent
<h3 style="color: white">MyCard</h3>
<h3 style="color: white">@Model.Text</h3>
@code{
[Parameter]
public MyViewModel Model {get; set;}
}
但是,当获取实例的问题不再是组件关心的问题时。谁负责?因为您的组件可以被其他组件使用,例如页面,所以现在是它们的责任。
MyViewModelDetail页面
@page "/myviewModel/Details/{Id}"
@inject MyViewModel vm
<MyViewModelDisplayComponent Model="vm" />
@code{
[Parameter]
public Guid Id {get; set;}
protected override async Task OnParametersSetAsync()
{
await vm.LoadDetails(Id);
}
}
MyViewModel
public class MyViewModel : NotifiableAndDisposableBase
{
private HttpClient _client;
public MyViewModel(HttpClient client)
{
_client = client;
}
public string Text { get; set; }
public async Task LoadDetails(Guid id)
{
Text = await client.GetFromJsonAsync<String>("YOUR_URL",id);
}
}
我认为,注入ViewModel是否明智,在很大程度上取决于上下文。根据您的输入,您正在ViewModel中使用HttpClient。因此,模型可以相应地加载(或发送(数据,如图所示。
然而,在该示例中,您可以看到您的组件只负责翻译";Blazor";比如URL绑定到一个变量,但不是更多。
我希望这能引发一些思考。