c# - Blazor 中的级联值和 EventCallback 与布局组件
问题描述
我想通过三个组件传递值和事件回调:首先我有 MainLayout,它是一个 LayoutComponent
@inherits LayoutComponentBase
<div class="cms-container">
<div class="header">
<div class="header-logo">
CMS
</div>
<div class="header-settings">
<div class="header-settings__alert">
<i class="fa fa-bell"></i>
<div class="header-settings__alert--no">
<div class="header-settings__alert--no__text">
2
</div>
</div>
<ul class="cms-dropdown">
<li class="cms-dropdown__alert">
<span class="cms-dropdown__alert--status"><i class="fa fa-info-circle font-danger"></i></span>
<span class="cms-dropdown__alert--left">Följ upp händelse</span><span class="cms-dropdown__alert--right">1 dgr</span>
</li>
<li class="cms-dropdown__alert">
<span class="cms-dropdown__alert--status"><i class="fa fa-info-circle font-success"></i></span>
<span class="cms-dropdown__alert--left">Tidrapport behöver lämnas in</span><span class="cms-dropdown__alert--right">3 dgr</span>
</li>
</ul>
</div>
<div class="header-settings__org">
<span class="header-settings__org--text">
Kanal10.se
</span>
<ul class="cms-dropdown">
<li class="cms-dropdown__normal">
<div class="cms-dropdown__normal--icon">
<i class="fa fa-tasks"></i>
</div>
<div class="cms-dropdown__normal--text">Uppgifter</div>
</li>
<li class="cms-dropdown__normal">
<div class="cms-dropdown__normal--icon">
<i class="fa fa-users"></i>
</div>
<div class="cms-dropdown__normal--text">Användare</div>
</li>
</ul>
</div>
<div class="header-settings__account">
<i class="fa fa-user"></i>
<ul class="cms-dropdown">
<li class="cms-dropdown__normal">
<div class="cms-dropdown__normal--icon">
<i class="fa fa-user"></i>
</div>
<div class="cms-dropdown__normal--text">Min profil</div>
</li>
<li class="cms-dropdown__normal">
<div class="cms-dropdown__normal--icon">
<i class="fa fa-money-check"></i>
</div>
<div class="cms-dropdown__normal--text">Lönebesked</div>
</li>
</ul>
</div>
<div class="header-settings__system">
<div class="header-settings__system--icon">
<i class="fa fa-cog"></i>
</div>
<ul class="cms-dropdown">
<li class="cms-dropdown__normal">
<div class="cms-dropdown__normal--icon">
<i class="fa fa-bars"></i>
</div>
<div class="cms-dropdown__normal--text">Menyer</div>
</li>
<li class="cms-dropdown__normal">
<div class="cms-dropdown__normal--icon">
<i class="fa fa-users"></i>
</div>
<div class="cms-dropdown__normal--text">Användare</div>
</li>
<li class="cms-dropdown__normal">
<div class="cms-dropdown__normal--icon">
<i class="fa fa-shield-alt"></i>
</div>
<div class="cms-dropdown__normal--text">Behörighetsgrupper</div>
</li>
</ul>
</div>
</div>
</div>
<div class="LeftNav">
<NavMenu />
</div>
<TelerikRootComponent>
<div class="cms-content">
@Body
</div>
</TelerikRootComponent>
<div class="footer">
<div class="footer-body">
<div class="footer-body__left">
</div>
<div class="footer-body__right">
<CascadingValue Value="visible">
<SaveAndCancelBtns OnBtnAction="?" />
</CascadingValue>
</div>
</div>
</div>
</div>
<BlazoredToasts Position="Blazored.Toast.Configuration.ToastPosition.TopCenter"
Timeout="3"
IconType="IconType.FontAwesome"
SuccessClass="success-toast-override"
SuccessIcon="fa fa-thumbs-up" />
@code {
private bool visible = false;
}
然后我有一个名为的子组件Buttons.razor
@if (visible == true)
{
<div class="footer-body__right--item">
<button class="btn btn-primary" @onclick="Save" type="submit">Save</button>
</div>
<div class="footer-body__right--item">
<button class="btn btn-cancel" @onclick="Cancel">Cancel</button>
</div>
}
[Parameter] public EventCallback<string> OnBtnAction { get; set; }
[Parameter] public bool visible { get; set; }
private void Save()
{
OnBtnAction.InvokeAsync("Save");
}
private void Cancel()
{
OnBtnAction.InvokeAsync("Cancel");
}
}
然后我有一个名为的组件剃须刀页面pageDetail.razor
@page "/pages/detail/{Id}"
@page "/pages/detail"
<div class="wrapper">
<div class="cms-content__title">
<div class="cms-content__title-left">
Page Detail
</div>
</div>
<div class="cms-content__page">
<div class="cms-content__page-all">
@if (cmsPage == null)
{
<ErrorMessage Message="Loading..." />
}
else
{
<div class="col-6">
<EditForm Model="cmsPage" OnValidSubmit="SavePage">
<DataAnnotationsValidator />
<ValidationSummary />
<div class="form-group">
<label for="PageTitle">Page Title</label>
<InputText @bind-Value="@cmsPage.PageTitle" class="form-control" id="PageTitle"></InputText>
</div>
<div class="form-group">
<label for="PageTitle">Page Descr</label>
<InputTextArea @bind-Value="@cmsPage.PageDescr" class="form-control" id="PageTitle"></InputTextArea>
</div>
<div class="form-group">
<label for="PageTitle">Page Url</label>
<InputText @bind-Value="@cmsPage.UrlName" class="form-control" id="PageTitle"></InputText>
</div>
<div class="form-group">
<label for="PageTitle">Page Type</label><br />
<TelerikComboBox Data="@cmsPageTypes" TextField="PageType" Width="100%" ValueField="PageTypeId" @bind-Value="selectedValue">
</TelerikComboBox>
<ValidationMessage For="@(() => cmsPage.PageTypeId)" />
</div>
<div class="form-group">
<label for="PageTitle">Parent Page</label><br />
<TelerikTreeView Data="@cmsPages" OnItemClick="@OnItemClickHandler">
<TreeViewBindings>
<TreeViewBinding IdField="PageId" TextField="PageTitle" ParentIdField="ParentId" HasChildrenField="false"></TreeViewBinding>
</TreeViewBindings>
</TelerikTreeView>
</div>
<button class="btn btn-primary" type="submit">Save</button>
<button class="btn btn-danger" @onclick="DeletePage">Delete</button>
<button class="btn btn-info" @onclick="BackToList">Back To List</button>
</EditForm>
</div>
}
</div>
</div>
</div>
@code{
"not sure how to implement the event button action"
}
我想要的是:
- 在 PageDetail 上设置可见参数,如果为 true,则显示 Buttons.razor 中的按钮或隐藏它们
- 当单击buttons.razor 中的按钮时,为那里的EditForm 处理PageDetail.razor 上的事件
问题是如何处理作为 LayoutComponent 的组件。不确定它如何符合逻辑。
如您所见,我已经开始实施它,但不确定如何连接不同的部分。
感谢帮助!彼得
解决方案
我建议您查看这篇文章:https ://chrissinty.com/3-ways-to-communicate-between-components-in-blazor/ ,但通过<CascadingParameter>
在布局中使用,您是其中的一部分。
在您的情况下,我不热衷于使用布尔值visible
作为级联参数,这有点简单。级联值也位于错误的位置,因为它需要包装@Body
渲染和按钮。
我会创建一个状态类并将该类级联到任何想要使用它的孩子,通过包装@Body
和<SaveAndCancelBtns ..>
<CascadingValue Value="buttonState" >
<TelerikRootComponent>
<div class="cms-content">
@Body
</div>
</TelerikRootComponent>
<div class="footer">
<div class="footer-body">
<div class="footer-body__left">
</div>
<div class="footer-body__right">
<SaveAndCancelBtns />
</div>
</div>
</div>
</CascadingValue>
您还需要在布局代码中添加一个值:
ButtonStates buttonState = new ButtonStates();
ButtonStates 类应该提供您需要的值和事件,例如
public class ButtonStates
{
public bool Visible { get; private set; }
// etc
}
我没有将所有代码放在这里,而是在 github 上为您创建了一个简单的示例 repo: https ://github.com/conficient/CascadingStateExample
请注意,我刚刚使用了一个简单的状态容器并event
从中传递事件。EventCallback<T>
专门用于连接 Razor 组件之间的事件。
推荐阅读
- discord - Discord.js:创建一个通道并在创建时执行 webhook 发送一些东西
- django - Django 模板中的嵌套变量
- list - 如何将我的收藏品与随机生成器连接并使用单词列表在 UNITY 2D 中生成
- r - 当我有不同年份的相同帧并且年份在名称中时,如何重写为循环?
- r - 找出总和等于 2020 的 n 个值
- python - 使用 LSTM RNN 预测斐波那契
- c++ - DeviceIoControl 协助
- html - html电子邮件中的照片不断切断
- c++ - C++ LNK2001 尝试使用外部变量时出错
- doctrine-orm - 尝试删除子行时出现外键错误