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 關注
- 103 瀏覽
添加回答
舉報