Blazor WASM - 分成多个组件 (MudBlazor)
Posted
技术标签:
【中文标题】Blazor WASM - 分成多个组件 (MudBlazor)【英文标题】:Blazo WASM - Separate into multiple components (MudBlazor) 【发布时间】:2021-12-07 21:38:34 【问题描述】:我有一个编辑表单,里面有多个 MudTabPanel。 问题是,我有很多此类的属性,我们决定分成多个面板,每个面板都包含一个具有不同表单/输入的编辑表单。
格式有点像这样(伪剃须刀代码):
<MudTabs>
<MudTabPanel Text="Section 1">
<EditForm>
<MudItem>
<EditField Property1>
<EditField Property2>
...
<EditField Property 10>
</EditForm>
</MudTabPanel>
<MudTabPanel Text="Section 2">
<EditForm>
<MudItem>
<EditField Propertyn11>
<EditField Propertyn12>
...
<EditField Property 20>
</EditForm>
</MudTabPanel>
..... lots of other panels here
<MudTabPanel Text="Section N">
<EditForm>
<MudItem>
<EditField Property98>
<EditField Property99>
...
<EditField Property100>
</EditForm>
</MudTabPanel>
</MudTabs>
问题是: 在这个剃须刀页面中,我有 +1000 行代码! VS 2022 Preview 正在努力为我提供不错的性能(在 UI 上似乎工作正常),但在 VS 中只修改一个属性是一件很痛苦的事情。
我正在考虑将每个面板移动到一个单独的组件中,并将我的实体作为参数传输。
但是: 1).现在,因为我将所有这些都用于单页剃须刀,所以在代码页上,假设我有方法 DoSomething(),我可以在每个面板上使用此方法。 如果我要拆分它们,我是否需要在每个组件上重复 DoSomething() ?有没有办法可以分享这种方法? 2).你认为这会影响 UI 的性能吗? 3).有没有更好的方法?
LE:更新了我的数据绑定示例
后面的代码:
private Article _article;
我的第一个选项卡中的一些绑定示例:
<MudNumericField T="int?" @bind-value="_article.ArticleID">
<MudSelect @bind-Value="_article.UnitPriceIntervals" OffsetY="true" Label="Unit Price Interval" Variant="Variant.Outlined" Margin="Margin.Dense" Dense="true">
@foreach (UnitPriceIntervals? item in (UnitPriceIntervals[])Enum.GetValues(typeof(UnitPriceIntervals)))
<MudSelectItem Value="item">@item</MudSelectItem>
</MudSelect>
现在,我的文章属性还可以包含对存储在不同 SQL 表中的其他数据类型的引用,并且可以根据搜索更改它们。 示例:
_article.GeneralText1 = 1234
【问题讨论】:
【参考方案1】:为什么不使用一个
@foreach (FieldAttributes fsa in cAtribs)
<MudTabPanel Text=@fsa.key>
<EditForm>
<MudItem>
@for(int i=0;i<fsa.Value.Count();i++)
<EditField @fsa.Value.ElementAt(i) />
</MudItem>
</EditForm>
</MudTabPanel>
循环,Dictionary<string, List<string>> cAtribs
.
字典的键是“Section 1”,...“Section N”,集合具有每个部分的属性名称。
您可以提前构建cAtribs
,或者动态构建,甚至使用反射。
【讨论】:
问题是,EditField 可以是一个属性的 NumericField 类型,另一个属性的 Select 类型,或者其他属性的其他类型。 我也很怀疑。所以这就是反射的用武之地。 显然只有通用形式才需要反射。如果您事先知道哪个字段是数字等,则很容易将此信息构建到 cAtrins 或其他结构中。【参考方案2】:这更像是一个评论而不是一个答案,但没有足够的间距将其放入评论中。
-
跟踪您所在的选项卡并仅加载特定选项卡的编辑表单。这将显着减少一次需要渲染的内容。比如:
@if (tabNo = 2)
// Edit Form 2
您不显示您的数据绑定,但请确保您使用视图数据服务来保存您的模型数据。
考虑为选项卡中的每个编辑表单使用一个组件?
多标签编辑器/向导有很多复杂性。您如何验证以及何时验证?你是后端一个模型/数据表吗?
如果您想了解更多细节,请添加评论,我会在今天晚些时候尝试整理一些演示代码。
===== 更新
首先将数据从编辑组件中取出并放入 ViewService。这是一个有线框架。
using System.Threading.Tasks;
namespace ***.Answers
public class ArticleViewService
//set up your data access
// load as Scoped Service - one per user session
public Article Article get; private set;
public Task GetArticle()
// Your get article code here
return Task.CompletedTask;
public Task SaveArticle()
// Your save article code here
return Task.CompletedTask;
接下来您的部分编辑组件。您的数据来自注入视图服务,并直接更新到同一服务中。组件之间不传递数据。
<h3>Section1</h3>
<EditForm EditContext="_editContext">
<InputText @bind-Value="ViewService.Article.Name"></InputText>
// or your mud editor components
.....
</EditForm>
@code
[Inject] private ArticleViewService ViewService get; set;
private EditContext _editContext;
protected override Task OnInitializedAsync()
_editContext = new EditContext(ViewService.Article);
return base.OnInitializedAsync();
然后是您的文章编辑器,使用 MudTabs。这应该跟踪活动选项卡并仅显示正确的部分组件。我没有对此进行测试,但它“应该”可以工作(我不使用 MudBlazor,也没有安装它。)
<MudTabs @bind-ActivePanelIndex="this.panelId">
<MudTabPanel Text="Item One" ID='"pn_one"'>
@if(this.PanelId = 1)
\\ Section 1 componwnt
</MudTabPanel>
<MudTabPanel Text="Item Two" ID='"pn_two"'>
@if (this.PanelId = 2)
\\ Section 2 componwnt
</MudTabPanel>
<MudTabPanel Text="Item Three" ID='"pn_three"'>
@if (this.PanelId = 2)
\\ Section 3 componwnt
</MudTabPanel>
</MudTabs>
@code
private int PanelId
get => _panelId;
set =>
if (value != _panelId )
_panelId = value;
StateHasChanged();
private int _panelId = 1;
【讨论】:
我已经编辑了我原来的问题,应该回答你关于第 2 点的问题 同时,我已经开始将它们移动到组件中,方法是将 _article 作为参数发送到每个单独的选项卡。以上是关于Blazor WASM - 分成多个组件 (MudBlazor)的主要内容,如果未能解决你的问题,请参考以下文章
C#:如何在 Blazor Wasm 托管中将动态 Razor 组件从服务器发送到客户端?