#blazor #blazor-server-side
#blazor #blazor-на стороне сервера
Вопрос:
Я только набираю скорость на стороне сервера Blazor (не webassembly), поэтому простите меня, если это глупый вопрос.
То, что я пытаюсь сделать, это иметь сервис, который можно использовать для отображения тостов. Библиотека компонентов, которую я использую, взята из Syncfusion. Я могу использовать это просто отлично обычным способом, когда он встроен в каждый компонент, где это необходимо.
<SfToast ID="toast_default" @ref="Toaster" CssClass="e-toast-success" content="@ViewModel.ToastMessage" Timeout="2000" Icon="e-meeting">
<ToastPosition X="Right" ></ToastPosition>
</SfToast>
Я могу использовать это в коде, и он отображает тост, как и ожидалось.
Но у меня есть много страниц, которые используют этот код, и я бы не хотел повторяться. Я хотел бы иметь возможность использовать вышеуказанное один раз в app.razor, а затем получить ссылку на него, а затем во всем приложении. Например, в onIntializedAsync
, я получаю ссылку на тостер, сохраните ее в внедренной службе. Затем я использую один и тот же сервис во всем приложении.
Я закодировал выше, но Toaster всегда имеет значение null в службе.
public class MessageService
{
public SfToast Toaster { get; set; }
public async Task SendMessage(string message)
{
if(this.Toaster!= null)
{
await this.Toaster.Show(new ToastModel() { Content = message });
}
}
}
Это код в App.razor. Я прошел через код, и он правильно устанавливает ссылку на Toaster, но когда служба сообщений пытается заставить ее использовать ее, она равна нулю.
@code {
public SfToast Toaster { get; set; }
protected override Task OnInitializedAsync()
{
this.MessageService.Toaster = this.Toaster;
return base.OnInitializedAsync();
}
}
Есть ли другой способ сделать это? Или я совершаю какую-то ошибку?
Комментарии:
1. Я внедряю службу с ограниченной областью действия. У этой службы есть
ShowMessage
метод. МойSfToast
находится только в основном макете. Основной макет задает делегат для службы с ограниченной областью действия, этот делегат может отображать сообщения через toast. Когда вы говорите службе с ограниченной областью, чтобы показать сообщение, он использует этот делегат.2. самый простой способ — использовать CascadeParameter
3. @nAviD, спасибо, я думаю, вы правы. Если вы хотите опубликовать в качестве ответа, я приму.
4. @daniherrera, я не уверен, что вы подразумеваете под «Основным макетом, устанавливающим делегат». Можете ли вы объяснить больше?
Ответ №1:
Основываясь на ответе @nAviD, я сделал это:
MainLayout.razor
настраивает параметр каскадирования. Компоненты тостера устанавливают @ref в MessageService.
@inherits LayoutComponentBase
@using JusticeOnTheWeb.Core
<CascadingValue Value="MessageService">
<div class="content">
@Body
</div>
</CascadingValue>
<SfToast ID="toast_default" @ref="MessageService.Toaster" CssClass="e-toast-success" Timeout="2000" Icon="e-meeting">
<ToastPosition X="Right"></ToastPosition>
</SfToast>
@code{
public MessageService MessageService { get; set; } = new MessageService();
}
Затем он потребляется MyComponent.razor
:
<SfButton @onclick="ShowMessage">Show Message</SfButton>
@code {
[CascadingParameter]
public MessageService MessageService { get; set; }
public void ShowMessage()
{
this.MessageService.Show("42");
}
}
Ответ №2:
Самый простой способ — использовать CascadeParameter
.