Layout 将blazor RenderFragment模板化为页面或组件中的布局
我想在blazor的布局页面中有可自定义的内容。我曾尝试向布局中添加renderfragment参数,并在组件中添加具有相同名称的化妆,但未在布局中渲染 乙二醇 但是头部内容在身体中呈现。有谁能解释一下怎么做,或者为什么在布局中不可能这样做。我发现唯一可行的方法是,如果我在渲染片段中更改绑定参数,它将不会刷新内容 灵活内容 在导航时清除 无需任何接线即可更新 mainplayout.razor.cs 用法 灵活内容 在导航时清除 无需任何接线即可更新 mainplayout.razor.cs 用法Layout 将blazor RenderFragment模板化为页面或组件中的布局,layout,rendering,blazor,Layout,Rendering,Blazor,我想在blazor的布局页面中有可自定义的内容。我曾尝试向布局中添加renderfragment参数,并在组件中添加具有相同名称的化妆,但未在布局中渲染 乙二醇 但是头部内容在身体中呈现。有谁能解释一下怎么做,或者为什么在布局中不可能这样做。我发现唯一可行的方法是,如果我在渲染片段中更改绑定参数,它将不会刷新内容 灵活内容 在导航时清除 无需任何接线即可更新 mainplayout.razor.cs 用法 灵活内容 在导航时清除 无需任何接线即可更新 mainplayout.razor.cs 用
前面的答案很接近,但对我来说不起作用。 我就是这样解决的: 主要布局: 在任何页面中使用:
现在只剩下一个问题。。。当你更改页面时,你必须在该页面中输入一个空的,以便将其清除前面的答案非常接近,但对我来说不起作用。 我就是这样解决的: 主要布局: 在任何页面中使用:
现在只剩下一个问题。。。当你更改页面时,你必须在该页面中添加一个空白以便清除它布赖恩·帕克的回答对我来说非常有效。但是,我需要两个标题片段,因此无法使用默认的ChildContent命名 主要布局: 用法:
布赖恩·帕克的回答对我来说非常有效。但是,我需要两个标题片段,因此无法使用默认的ChildContent命名 主要布局: 用法:
无法更新属性。你必须调用一个函数,就像我必须设置片段一样,然后调用状态改变了。事实上,直接更新属性应该会给你一个警告。嗨,谢谢你的帮助。是的,上面的伪代码不起作用。我希望找到一种方法,当版面设置器中的内容发生更改时,触发标题重新呈现。此时,呈现的内容在布局中是静态的,因此如果我更改属性,它只会更新内容,而不会更新布局。我向该页面添加了另一个解决方案。有点复杂,但我对结果很满意。你不能更新属性。你必须调用一个函数,就像我必须设置片段一样,然后调用状态改变了。事实上,直接更新属性应该会给你一个警告。嗨,谢谢你的帮助。是的,上面的伪代码不起作用。我希望找到一种方法,当版面设置器中的内容发生更改时,触发标题重新呈现。此时,呈现的内容在布局中是静态的,因此如果我更改属性,它只会更新内容,而不会更新布局。我向该页面添加了另一个解决方案。有点复杂,但我对结果很满意。
layout.razor:
<header>
@HeaderContent
</header>
@body
@code
{
[Parameter] public RenderFragment HeaderContent { get; set; }
}
component.razor:
<HeaderContent>
<p>my page specific content</p>
</HeaderContnt>
@inherits LayoutComponentBase
...
<div class="top-row px-4">
@headerContent
</div>
<div class="content px-4">
<CascadingValue Value="this">
@Body
</CascadingValue>
</div>
...
@code {
RenderFragment headerContent => setHeader?.ChildContent;
SetHeader setHeader;
public void SetHeader(SetHeader setHeader)
{
this.setHeader = setHeader;
Update();
}
public void Update() => StateHasChanged();
}
public class SetHeader : ComponentBase, IDisposable
{
[CascadingParameter]
public MainLayout MainLayout { get; set; }
[Parameter]
public RenderFragment ChildContent { get; set; }
protected override void OnInitialized()
{
MainLayout.SetHeader(this);
base.OnInitialized();
}
protected override bool ShouldRender()
{
var shouldRender = base.ShouldRender();
if (shouldRender)
{
MainLayout.Update();
}
return base.ShouldRender();
}
public void Dispose()
{
MainLayout?.SetHeader(null);
}
}
<SetHeader>
<p>Current count: @currentCount</p>
</SetHeader>
<div class="main">
<div class="top-row px-4">
@headerContent
@*<a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a>*@
</div>
<div class="content px-4">
<CascadingValue Value="this">
@Body
</CascadingValue>
</div>
</div>
@code {
RenderFragment headerContent => setHeader?.ChildContent;
SetHeader setHeader;
public void SetHeader(SetHeader setHeader)
{
if (setHeader == null) return;
this.setHeader = setHeader;
this.setHeader.OnChange += StateHasChanged;
}
}
public class SetHeader : ComponentBase, IDisposable
{
[CascadingParameter] public MainLayout MainLayout { get; set; }
[Parameter] public RenderFragment ChildContent { get; set; }
public event Action OnChange;
protected override void OnInitialized()
{
MainLayout.SetHeader(this);
Update();
base.OnInitialized();
}
public void Update()
{
OnChange?.Invoke();
StateHasChanged();
}
public void Dispose()
{
MainLayout?.SetHeader(null);
}
}
<SetHeader @ref="@setHeader">
<p>Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
</SetHeader>
SetHeader setHeader;
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
setHeader.Update();
}
<div class="main">
<div class="top-row px-4">
@FirstHeader
</div>
<div class="top-row px-4">
@SecondHeader
</div>
<div class="content px-4">
<CascadingValue Value="this">
@Body
</CascadingValue>
</div>
</div>
@code
{
RenderFragment FirstHeader => _setHeader?.FirstHeaderTemplate;
RenderFragment SecondHeader => _setHeader?.SecondHeaderTemplate;
SetHeader _setHeader;
public void SetHeader(SetHeader setHeader)
{
_setHeader = setHeader;
Update();
}
public void Update() => StateHasChanged();
}
public class SetHeader : ComponentBase, IDisposable
{
[CascadingParameter]
public MainLayout MainLayout { get; set; }
[Parameter]
public RenderFragment FirstHeaderTemplate { get; set; }
[Parameter]
public RenderFragment SecondHeaderTemplate { get; set; }
protected override void OnInitialized()
{
MainLayout.SetHeader(this);
base.OnInitialized();
}
protected override bool ShouldRender()
{
var shouldRender = base.ShouldRender();
if (shouldRender)
{
MainLayout.Update();
}
return base.ShouldRender();
}
public void Dispose()
{
MainLayout?.SetHeader(null);
}
}
<SetHeader>
<FirstHeaderTemplate>
<LoginDisplay />
</FirstHeaderTemplate>
<SecondHeaderTemplate>
<p>Current count: @currentCount</p>
</SecondHeaderTemplate>
</SetHeader>