从 Blazor 中的页面组件调用 MainLayout 中的方法
Call method in MainLayout from a page component in Blazor
我有一个带有 MainLayout
页面的 Blazor 应用程序,它有一个 @Body
来加载实际页面内容。
在我的例子中 Index.razor
被加载到 MainLayout
页面中。
有没有办法从父页面中的子页面 (Index.razor) 调用方法? MainLayout.razor
?
示例:
MainLayout.razor
<div class="content">
<ul class="menu">
<li>menu item 1</li>
</ul>
@Body
</div>
@code
{
public async Task Test()
{
await JsRuntime.InvokeAsync<object>("console.log", "test parent");
}
}
Index.razor
<h1>This is the index page</h1>
<button @onclick="(async () => await btn_clicked())">Call parent method</button>
@code
{
// Call method in MainLayout
public async Task btn_clicked()
{
await parent.Test();
}
}
您可以结合级联值和 EventCallback
来完成此操作。
首先,为您的 Test
创建事件回调。为此,请在 MainLayout.razor 中添加以下代码。
EventCallback btn_clicked => EventCallback.Factory.Create(this, Test);
或者,要确保只创建此 object 一次,您可以使用以下内容:
EventCallback _btn_clicked = EventCallback.Empty;
EventCallback btn_clicked {
get {
if (_btn_clicked.Equals(EventCallback.Empty))
_btn_clicked = EventCallback.Factory.Create(this, Test);
return _btn_clicked;
}
}
接下来,确保将此事件回调级联到 body。
<CascadingValue Value=btn_clicked >
@Body
</CascadingValue>
现在,在您的 Index.razor 代码中,设置 属性:
[CascadingParameter]
public EventCallback btn_clicked { get; set; }
谢谢。第一个答案正是我需要的,虽然我需要传入一个参数,所以它与布局相同,除了:
在MainLayout.razor中:
public EventCallback<string> EventName => EventCallback.Factory.Create<string>(this, MethodName);
在Index.razor中:
[CascadingParameter]
protected EventCallback<string> EventName { get; set; }
调用方法:
EventName.InvokeAsync("Name");
回调方法有效,但仍然相当有限,我采用的方法是使用从 Xamarin.Forms...
克隆的“消息中心”
https://github.com/aksoftware98/blazor-utilities
https://www.nuget.org/packages/AKSoftware.Blazor.Utilities/
它非常简单、灵活,并且更像一个跨组件的 pubsub 消息传递系统,这有很多好处。
因此,无论嵌套状态和位置如何,您都可以将事件“广播”到单个或多个组件 - 非常灵活且有用。取自他们的文档...
在您的 _imports.razor
中放置一个 using
@using AKSoftware.Blazor.Utilities
然后在 MainLayout.razor
中添加订阅者
public void SubscribeToMessage()
{
MessagingCenter.Subscribe<Component1, string>(this, "greeting_message",
(sender, value) =>
{
// Do actions against the value
// If the value is updating the component make sure to call
string greeting = $"Welcome {value}";
StateHasChanged(); // To update the state of the component
});
}
以及您想要的任何组件中的发布者
public void SendMessage()
{
string valueToSend = "Hi from Component 1";
MessagingCenter.Send(this, "greeting_message", valueToSend);
}
您可以将订阅者和发件人放在组件的任意组合中。我一直在做一个实时日期同时更新多个组件的项目,这是一个很好的解决方案,它允许我将所有集线器连接逻辑放在 MainLayout.razor 中,然后调用并响应所有根据需要添加组件,防止创建多个集线器连接,并与级联状态协同工作。
我有一个带有 MainLayout
页面的 Blazor 应用程序,它有一个 @Body
来加载实际页面内容。
在我的例子中 Index.razor
被加载到 MainLayout
页面中。
有没有办法从父页面中的子页面 (Index.razor) 调用方法? MainLayout.razor
?
示例:
MainLayout.razor
<div class="content">
<ul class="menu">
<li>menu item 1</li>
</ul>
@Body
</div>
@code
{
public async Task Test()
{
await JsRuntime.InvokeAsync<object>("console.log", "test parent");
}
}
Index.razor
<h1>This is the index page</h1>
<button @onclick="(async () => await btn_clicked())">Call parent method</button>
@code
{
// Call method in MainLayout
public async Task btn_clicked()
{
await parent.Test();
}
}
您可以结合级联值和 EventCallback
来完成此操作。
首先,为您的 Test
创建事件回调。为此,请在 MainLayout.razor 中添加以下代码。
EventCallback btn_clicked => EventCallback.Factory.Create(this, Test);
或者,要确保只创建此 object 一次,您可以使用以下内容:
EventCallback _btn_clicked = EventCallback.Empty;
EventCallback btn_clicked {
get {
if (_btn_clicked.Equals(EventCallback.Empty))
_btn_clicked = EventCallback.Factory.Create(this, Test);
return _btn_clicked;
}
}
接下来,确保将此事件回调级联到 body。
<CascadingValue Value=btn_clicked >
@Body
</CascadingValue>
现在,在您的 Index.razor 代码中,设置 属性:
[CascadingParameter]
public EventCallback btn_clicked { get; set; }
谢谢。第一个答案正是我需要的,虽然我需要传入一个参数,所以它与布局相同,除了:
在MainLayout.razor中:
public EventCallback<string> EventName => EventCallback.Factory.Create<string>(this, MethodName);
在Index.razor中:
[CascadingParameter]
protected EventCallback<string> EventName { get; set; }
调用方法:
EventName.InvokeAsync("Name");
回调方法有效,但仍然相当有限,我采用的方法是使用从 Xamarin.Forms...
克隆的“消息中心”https://github.com/aksoftware98/blazor-utilities
https://www.nuget.org/packages/AKSoftware.Blazor.Utilities/
它非常简单、灵活,并且更像一个跨组件的 pubsub 消息传递系统,这有很多好处。
因此,无论嵌套状态和位置如何,您都可以将事件“广播”到单个或多个组件 - 非常灵活且有用。取自他们的文档...
在您的 _imports.razor
中放置一个 using@using AKSoftware.Blazor.Utilities
然后在 MainLayout.razor
中添加订阅者public void SubscribeToMessage()
{
MessagingCenter.Subscribe<Component1, string>(this, "greeting_message",
(sender, value) =>
{
// Do actions against the value
// If the value is updating the component make sure to call
string greeting = $"Welcome {value}";
StateHasChanged(); // To update the state of the component
});
}
以及您想要的任何组件中的发布者
public void SendMessage()
{
string valueToSend = "Hi from Component 1";
MessagingCenter.Send(this, "greeting_message", valueToSend);
}
您可以将订阅者和发件人放在组件的任意组合中。我一直在做一个实时日期同时更新多个组件的项目,这是一个很好的解决方案,它允许我将所有集线器连接逻辑放在 MainLayout.razor 中,然后调用并响应所有根据需要添加组件,防止创建多个集线器连接,并与级联状态协同工作。