1 回答
TA贡献1796条经验 获得超4个赞
扩展我留下的评论,你可以解决这个问题的一种方法是让你BaseViewModel成为一个抽象类并拥有从它派生的具体类。所以UserViewModel和AdminViewModel。这两个具体类将成为两者的模型,TableView并将TableManagentView负责告诉“外部世界”如何标记字段。
基类有两个主要方面(除了你的普通字段):一个Dictionary<string, string>包含标签的抽象和一个从列表中获取标签的方法:string GetLabel(string propName). 所以是这样的:
public abstract class BaseViewModel
{
protected abstract Dictionary<string, string> Labels { get; }
public string UserComment { get; set; }
public string GetLabel(string propName)
{
if (!Labels.TryGetValue(propName, out var label))
throw new KeyNotFoundException($"Label not found for property name: {propName}");
return label;
}
}
然后创建两个派生类User和Admin:
public sealed class UserViewModel : BaseViewModel
{
protected override Dictionary<string, string> Labels => new Dictionary<string, string>
{
{ nameof(UserComment), "User label" }
};
}
public sealed class AdminViewModel : BaseViewModel
{
protected override Dictionary<string, string> Labels => new Dictionary<string, string>
{
{ nameof(UserComment), "Admin label" }
};
}
他们只Dictionary<string, string>为基类上的每个字段实现并设置适当的文本。
接下来,将您的更改BaseViewComponent为:
查看:
@model DisplayNameTest.Models.BaseViewModel
<h3>Hello from my View Component</h3>
<!-- Gets the label via the method on the base class -->
<p>@Model.GetLabel(nameof(BaseViewModel.UserComment))</p>
<p>@Model.UserComment)</p>
ComponentView 类(现在更简单了)
public IViewComponentResult Invoke(BaseViewModel viewModel)
{
return View(viewModel);
}
最后,改变你的观点TableView和TableManagentView这个:
@model WebApp.Models.AdminViewModel
@{
Layout = null;
}
<h1>Admin View</h1>
<div>
@await Component.InvokeAsync("Base", Model)
</div>
和控制器:
public IActionResult Index()
{
var adminViewModel = new AdminViewModel { UserComment = "some comment from admin" };
return View(adminViewModel);
}
现在,当您导航到 时TableView,您会将 a 传递UserViewModel给 the BaseViewComponent,它会找出正确的标签。引入新字段现在需要您更改视图模型,将新条目添加到字典中。
它并不完美,但我认为这是解决它的好方法。到目前为止,我还不是 MVC 专家,所以也许其他人也可以想出一种更自然的方法来做到这一点。我还准备了一个工作示例应用程序并推送到 GitHub。你可以在这里查看:aspnet-view-component-demo。希望它以某种方式有所帮助。
- 1 回答
- 0 关注
- 165 浏览
添加回答
举报
