从局部视图通过 signalr 发送消息

Send message by signalr from partial view

在我的剃须刀页面应用程序中,我需要从局部视图发送消息。我用信号器。 我的剃须刀页面:

@page 
@model Pokerweb.Pages.GamePageModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

<script src="~/js/signalr/dist/browser/signalr.js"></script>
<script src="~/js/chat.js"></script>

<div id="grid"></div>

<script>

    $(function () {
        $('#load').on('click', function () {
            $('#grid').load('/GamePage?handler=PlayersPartial');
        });
    });
</script>

部分:

@using Pokerweb.Models
@model Room

<h3>@Model.Sum</h3>

<table class="table table-striped">
    @foreach (var player in Model.Players)
    {
        <tr>
            <td>@player.PlayerName</td>
            <td>@player.Money</td>
        </tr>
    }
</table>

<input type="range" min="1" max="100" value="50" class="slider" id="myRange">

<button class="btn btn-primary" id="sendButton">Send</button>

Chat.js:

"use strict";

window.onload = function () {

    var connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build();
    
    connection.on("ReceiveMessage", function () {
        $(function () {
            $('#grid').load('/GamePage?handler=PlayersPartial');
        });
    });

    connection.start().then(function () {
        document.getElementById("sendButton").disabled = false;
    }).catch(function (err) {
        return console.error(err.toString());
    });

    document.getElementById("sendButton").addEventListener("click", function (event) {
        connection.invoke("SendMessage").catch(function (err) {
            return console.error(err.toString());
        });
        event.preventDefault();
    });
};

通过 sendButton 单击我想要 fire impuls,它在数据库中提供了一些更改,最后它为某些用户刷新了部分视图。因为结果应该是打扑克的网页。几乎所有的事情都发生在一个房间的玩家之间。所以我想激发冲动,它在 chathub 中对数据库做一些事情,然后向一个房间里的一群人发送空消息,以更新从更新的数据库生成的部分视图。

我的问题是此处的代码中发送按钮不起作用。应该是因为js是在发送按钮构建之前执行的。我尝试了很多方法来解决这个问题,但没有一个有效。所以我需要得到有效的解决方案。感谢大家的重播,对不起我的英语。

一个问题似乎是当您尝试使用 document.getElementById("sendButton") select 时 <button> 元素不存在。您应该尝试在加载部分后附加处理程序,例如:

"use strict";

function appendHandlers() {
    document.getElementById("sendButton").addEventListener("click", function (event) {
        connection.invoke("SendMessage").catch(function (err) {
            return console.error(err.toString());
        });
        event.preventDefault();
    });
}

window.onload = function () {

    var connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build();
    
    connection.on("ReceiveMessage", function () {
        $(function () {
            $('#grid').load('/GamePage?handler=PlayersPartial').then(appendHandlers);
        });
    });

    connection.start().then(function () {
        document.getElementById("sendButton").disabled = false;
    }).catch(function (err) {
        return console.error(err.toString());
    });
};

My problem is that in code here isn't send button working. It should be because js is executed before send button is build.

正如您提到的,当 js 代码执行并尝试将点击事件附加到按钮 "sendButton" 时,它不会在当前 DOM 中呈现,这导致了问题。

并且在您的代码中,我们可以发现 ID 为 "grid"

容器的内容将在客户端收到新消息后动态更新,按钮 "sendButton" 也将重新渲染。

为了达到你的要求,你可以尝试在主页面使用一个虚拟按钮(隐藏按钮),当用户点击发送按钮时触发它调用集线器方法,如下所示。

<div id="grid"></div>

<input id="send_btn_trigger" type="button" style="visibility:hidden;" />

@section scripts{
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

    <script src="~/js/signalr/dist/browser/signalr.js"></script>
    <script src="~/js/chat.js"></script>

    <script>

        $(function () {
            $('#load').on('click', function () {
                $('#grid').load('/GamePage?handler=PlayersPartial', function () {
                    updategrid();
                });
            });
        });

        function triggerSendEvent() {
            console.log("triggerSendEvent");
            $("#send_btn_trigger").click();
        }
    </script>
}

部分页面

@model Room

<h3>@Model.Sum</h3>

<table class="table table-striped">
    @foreach (var player in Model.Players)
    {
        <tr>
            <td>@player.PlayerName</td>
            <td>@player.Money</td>
        </tr>
    }
</table>

<input type="range" min="1" max="100" value="50" class="slider" id="myRange">

<button class="btn btn-primary" id="sendButton" onclick="triggerSendEvent()" disabled>Send</button>

Chat.js

"use strict";

function updategrid() {
    //console.log("updategrid");
    var connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build();

    connection.on("ReceiveMessage", function () {

        $('#grid').load('/GamePage?handler=PlayersPartial', function () {
            document.getElementById("sendButton").disabled = false;
        });    
    });

    connection.start().then(function () {
        document.getElementById("sendButton").disabled = false;
    }).catch(function (err) {
        return console.error(err.toString());
    });

    document.getElementById("send_btn_trigger").addEventListener("click", function (event) {
        //console.log("send_btn_trigger");
        connection.invoke("SendMessage").catch(function (err) {
            return console.error(err.toString());
        });

        event.preventDefault();
    });
}

测试结果