解决点击发送按钮后员工页面Bootstrap Alert重复弹窗失效问题
Hey there! Let's break down why your Bootstrap Alert stops popping up after the first close, and fix it with straightforward changes:
What's Going Wrong?
Bootstrap's default data-dismiss="alert" doesn't just hide the alert—it removes the entire alert element from the DOM. So when you send a second message, there's no alert left to update! Also, your backend currently only saves the message to the database, but doesn't actively push it to employee clients via SignalR. Let's fix both issues.
Step 1: Fix the Alert's Close Behavior (Employee Page)
We'll modify the alert to hide instead of delete itself, and make sure it reappears when a new message arrives:
<div class="container"> <!-- Add an ID to target the alert, start hidden to avoid empty alert on load --> <div id="notificationAlert" class="alert alert-warning" style="display: none;"> <!-- Replace data-dismiss with a custom hide function --> <a href="#" class="close" onclick="hideAlert()" aria-label="close">×</a> <p id="output"></p> </div> </div> <script src="~/lib/signalr.js"></script> <script type="text/javascript"> // Custom function to hide the alert (instead of deleting it) function hideAlert() { document.getElementById('notificationAlert').style.display = 'none'; } // Initialize SignalR connection var connection = new signalR.HubConnectionBuilder() .withUrl('/speedalarmhub') .build(); // Handle incoming messages connection.on('ReceiveMessage', function (message) { const alertElement = document.getElementById('notificationAlert'); const outputElement = document.getElementById("output"); // Show the alert and update its content alertElement.style.display = 'block'; // Use textContent instead of innerHTML to avoid XSS risks outputElement.textContent = message; }); // Start the connection connection.start() .then(function () { console.log('SignalR connection started'); // Remove the old connection.invoke('SendMessage')—we'll push from the backend instead }) .catch(error => { console.error(error.message); }); </script>
Step 2: Add Backend SignalR Push Logic
Your admin page's submit handler saves the message to the database, but doesn't send it to employees. Let's fix that:
2.1 Create a SignalR Hub Class
using Microsoft.AspNetCore.SignalR; public class SpeedAlarmHub : Hub { // This method can be called directly, but we'll use backend-initiated pushes public async Task SendMessage(string message) { await Clients.All.SendAsync("ReceiveMessage", message); } }
2.2 Update Your Admin Page Model
Inject the SignalR hub context and push the message after saving to the database:
using Microsoft.AspNetCore.SignalR; // Replace "YourAdminPageModel" with your actual page model class name public class YourAdminPageModel : PageModel { private readonly IHubContext<SpeedAlarmHub> _hubContext; // Inject the hub context via constructor public YourAdminPageModel(IHubContext<SpeedAlarmHub> hubContext) { _hubContext = hubContext; } public async Task OnPostSubmit(NotificationModel notif) { DateTime datenow = DateTime.Now; CreateNotification(datenow, notif.Bericht); // Push the message to all connected employee clients await _hubContext.Clients.All.SendAsync("ReceiveMessage", notif.Bericht); } public void CreateNotification(DateTime convdayid, string Bericht) { var cs = Database.Database.Connector(); using var con = new NpgsqlConnection(cs); con.Open(); var sql = "INSERT INTO notification(bericht, datumnu) VALUES(@Msg, @Date)"; using var cmd = new NpgsqlCommand(sql, con); cmd.Parameters.AddWithValue("Msg", Bericht); cmd.Parameters.AddWithValue("Date", convdayid); cmd.Prepare(); cmd.ExecuteNonQuery(); // No need for con.Close()—the using block auto-releases the connection } }
2.3 Register SignalR in Your App
Make sure SignalR is set up in your Program.cs (or Startup.cs if using older .NET):
var builder = WebApplication.CreateBuilder(args); // Add SignalR services builder.Services.AddSignalR(); var app = builder.Build(); // Map the SignalR hub route app.MapHub<SpeedAlarmHub>("/speedalarmhub"); app.Run();
Bonus: Add Smooth Animations (Optional)
For a nicer user experience, add Bootstrap's fade animation:
- Update the alert HTML:
<div id="notificationAlert" class="alert alert-warning fade" style="display: none;"> - Modify the
hideAlertfunction to wait for the animation to finish:function hideAlert() { const alertElement = document.getElementById('notificationAlert'); alertElement.classList.remove('show'); // Wait for fade-out animation to complete before hiding setTimeout(() => { alertElement.style.display = 'none'; }, 300); } - Update the
ReceiveMessagehandler to add theshowclass:connection.on('ReceiveMessage', function (message) { const alertElement = document.getElementById('notificationAlert'); const outputElement = document.getElementById("output"); alertElement.style.display = 'block'; alertElement.classList.add('show'); outputElement.textContent = message; });
内容的提问来源于stack exchange,提问作者anonD

