بر اساس آموزش مدیریت حالت در Blazor، قصد
داریم یک سرویس پیام هشدار ساده، ولی زیبا را بوسیله کامپوننت Alert بوت استرپ ۵ ، بدون
استفاده از توابع جاوا اسکریپتی، طراحی کنیم.
در ابتدا کتابخانههای css زیر را بوسیله LibMan به پروژه اضافه کرده و مداخل فایلهای را css نیز اضافه میکنیم:
{
"version": "1.0",
"defaultProvider": "cdnjs",
"libraries": [
{
"provider": "unpkg",
"library": "bootstrap@5.0.0",
"destination": "wwwroot/lib/bootstrap"
},
{
"provider": "unpkg",
"library": "open-iconic@1.1.1",
"destination": "wwwroot/lib/open-iconic"
},
{
"provider": "unpkg",
"library": "animate.css@4.1.1",
"destination": "wwwroot/lib/animate"
},
{
"provider": "unpkg",
"library": "bootstrap-icons@1.5.0",
"destination": "wwwroot/lib/bootstrap-icons/"
}
]
}
در ادامه کلاس سرویس پیام را پیاده سازی و آن را با طول عمر Scoped به سیستم
تزریق وابستگیهای برنامه، معرفی میکنیم:
public enum AlertType
{
Success,
Info,
Danger,
Warning
}
public class AlertService
{
public void ShowAlert(string message, AlertType alertType, string animate = "animate__fadeIn")
{
OnChange?.Invoke(message, alertType,animate);
}
public event Action<string,AlertType, string> OnChange;
}
services.AddScoped<AlertService>();
توضیحات:
در کدهای نهایی برنامه قرار است به این نحو کار نمایش Alertها را در کامپوننتهای مختلف انجام دهیم:
@inject AlertService AlertService
@code {
private void Success()
{
AlertService.ShowAlert("Success!", AlertType.Success);
}
این کامپوننتها هم الزاما در یک سلسله مراتب قرار ندارند و ارسال پارامترهای آبشاری به آنها صدق نمیکند. به همین جهت یک سرویس Scoped را طراحی کردهایم که در برنامههای Blazor WASM، طول عمر آن، با طول عمر برنامه یکی است؛ یعنی به صورت Singleton عمل میکند و در تمام کامپوننتها و سرویسهای دیگر نیز در دسترس خواهد بود. زمانیکه متد AlertService.ShowAlert
فراخوانی میشود، سبب بروز رویداد OnChange خواهد شد و تمام گوش دهندگان به آن که در اینجا تنها کامپوننت Alert سفارشی ما است (برای مثال آنرا در MainLayout.razor قرار میدهیم )، مطلع شده و بلافاصله محتوایی را نمایش میدهند. کدهای کامپوننت Alert.razor
@inject AlertService AlertService
@implements IDisposable
<style>
.alert-show {
display: flex;
flex-direction: row;
}
.alert-hide {
display: none;
}
</style>
<div style="z-index: 5">
<div " + "alert-show" :"alert-hide")">
<i width="24" height="24"></i>
<div>
@Message
</div>
<button type="button" data-bs-dismiss="alert" aria-label="Close" @onclick="CloseClick"></button>
</div>
</div>
@code {
AlertType AlertType { get; set; }
string Icon { get; set; }
string Css { get; set; }
string Animation { get; set; }
private bool IsVisible { get; set; }
private string Message { get; set; }
System.Timers.Timer _alertTimeOutTimer;
protected override void OnInitialized()
{
AlertService.OnChange += ShowAlert;
}
private void ShowAlert(string message, AlertType alertType, string animate)
{
_alertTimeOutTimer = new System.Timers.Timer
{
Interval = 5000,
Enabled = true,
AutoReset = false
};
_alertTimeOutTimer.Elapsed += HideAlert;
Message = message;
switch (alertType)
{
case AlertType.Success:
Css = "bg-success";
Icon = "bi-check-circle";
break;
case AlertType.Info:
Css = "bg-info";
Icon = "bi-info-circle-fill";
break;
case AlertType.Danger:
Css = "bg-danger";
Icon = "bi-exclamation-circle";
break;
case AlertType.Warning:
Css = "bg-warning";
Icon = "bi-exclamation-triangle-fill";
break;
default:
Css = Css;
break;
}
AlertType = alertType;
Animation = animate;
IsVisible = true;
InvokeAsync(StateHasChanged);
}
private void HideAlert(Object source, System.Timers.ElapsedEventArgs e)
{
IsVisible = false;
InvokeAsync(StateHasChanged);
_alertTimeOutTimer.Close();
}
public void Dispose()
{
if (AlertService != null) AlertService.OnChange -= ShowAlert;
if (_alertTimeOutTimer != null)
{
_alertTimeOutTimer.Elapsed -= HideAlert;
_alertTimeOutTimer?.Dispose();
}
}
private void CloseClick()
{
IsVisible = false;
_alertTimeOutTimer.Close();
InvokeAsync(StateHasChanged);
}
}
توضیحات: همانطور که مشاهده میکنید، کامپوننت Alert، از سرویس تزریق شدهی AlertService استفاده میکند. بنابراین در هرجائی از برنامه که AlertService.ShowAlert فراخوانی شود، سبب بروز رویداد OnChange شده و به این ترتیب کامپوننت فوق، Alert ای را نمایش میدهد که البته نمایش آن به همراه یک Timeout و محو شدن خودکار نیز هست. برای استفاده از کامپوننت Alert.razor، آنرا در صفحه اصلی MainLayout یا هرجای دلخواهی قرار میدهیم:
و سپس با تزریق AlertService
در کامپوننت مورد نظر (که محل آن مهم نیست) و اجرای متد ShowAlert آن بههمراه پارامترهای آن، پیام هشداری را که توسط MainLayout نمایش داده میشود، مشاهده خواهیم کرد.