使用 SignalR 在 ASP .NET CORE 中自定义实现类似按钮

Custom implementing like button in ASP .NET CORE with SignalR

大家好,

抱歉,如果我的问题与某些问题重复,但我没有找到解决问题的方法。

但是,我正在尝试在我的 asp.net 核心 mvc 应用程序中为 post 实现自定义点赞按钮并且一切正常,除了当我点击点赞按钮时,它会改变颜色(像在 facebook 上,蓝色等)不仅适用于当前登录的用户,而且适用于所有登录的用户。但是当其他用户刷新window,一切又恢复正常了...

我想要的是,当我点击 "like" 按钮时,为所有人更新 "like counter" 并为我更改颜色(前几天我回来时,我知道我喜欢 post.)

有人知道如何完成这个吗? 这是我的代码

Index.cshtml

@using Fitness_Centar.Data
@using Fitness_Centar.Data.Models
@using Fitness_Centar.Web.Areas.ModulClan.ViewModels
@using Fitness_Centar.Web.Helper
@model List<TimelineVM>

@{
    ViewData["Title"] = "Index";
    MyContext _ctx = (MyContext)ViewData["_ctx"];

User u = Context.GetLoggedUser();
int userId = -1;
if (u.Coach != null)
{
    userId = u.Coach.CoachId;
}
if (u.Employee != null)
{
    userId = u.Employee.EmployeeId;
}
if (u.Member != null)
{
    userId = u.Member.MemberId;
}
}

<div class="row">
<div class="col-sm-12 col-md-9 col-lg-9">
    <div class="box box-info custom aktivnosti">
        <div class="box-header with-border padding-l-25">
            <h3 class="box-title">Activities</h3>
        </div>

        <div class="box-body">
            @foreach (var p in Model)
            {
                <div id="@p.Post.PostClanovaId" class="post">
                    <div class="user-info">
                        <img class="img-circle img-bordered-sm" src="~/AdminLTE/dist/img/avatar5.png" />
                        <div class="desc">
                            <span class="username">@p.Post.User.Name @p.Post.User.LastName</span>
                            <span class="post-description">Published: @p.Post.PostDate</span>
                        </div>
                    </div>
                    <div class="post-content text-justify">
                        <p>@p.Post.Content</p>
                    </div>
                    <div class="post-footer">
                        @{int n = p.Post.PostId + 1594;}
                        @{
                            var c = _ctx.Likes.Where(x => x.UserId == userId && x.PostId == p.Post.PostId).FirstOrDefault();

                            if (c != null && c.UserId == userId)
                            {
                                <a href="" id="post-@n" class="likeButton link-black liked" data-postid="@p.Post.PostId" data-userid="@userId">
                                    <i class="fa fa-thumbs-o-up margin-r-5"></i>
                                    Like
                                </a>
                            }
                            else
                            {
                                <a href="" id="post-@n" class="likeButton link-black" data-postid="@p.Post.PostId" data-userid="@userId">
                                    <i class="fa fa-thumbs-o-up margin-r-5"></i>
                                    Like
                                </a>
                            }
                        }
                        <div class="num-of-likes" id="post-@n-numOfLikes">
                            @p.Likes.Count()
                            <span class="usersThatLiked">
                                @{
                                    string g = "";
                                    foreach (var l in p.Likes)
                                    {
                                        g += l.User.Ime + " " + l.Clan.Prezime;
                                    }
                                    @g;
                                }
                            </span>
                        </div>
                        <div class="comment pull-right">
                            <a href="#" class="link-black">
                                <i class="fa fa-comments-o margin-r-5"></i>
                                Comments
                            </a>
                        </div>
                        <div class="input-group">
                            <input type="text" class="form-control" placeholder="Komentiraj...">
                            <span class="input-group-btn">
                                <button type="button" class="btn btn-info btn-flat"><i class="fa fa-check"></i></button>
                            </span>
                        </div>
                    </div>
                </div>
            }
        </div>
    </div>
</div>

javascript.js

"use strict";
var $connection = new signalR.HubConnectionBuilder().withUrl("/ModulClan/Helper/LajkHub").build();

$(".likeButton").prop("disabled", true);

$connection.on("ReceiveMessage", function (numOfLikes, postId) {
    var x = postId + 1594;
    var s = "#post-" + x;
    if ($(s).hasClass("liked")) {
        $(s).removeClass("liked");
    } else {
        $(s).addClass("liked");
    }
    $(s + "-num-of-likes").text(numOfLikes);
});

$connection.start().then(function () {
    $(".likeButton").prop("disabled", false);
}).catch(function (err) {
    return console.error(err.toString());
});


$(".likeButton").bind("click", function (event) {
    var userId = $(this).attr("data-userid");
    var postId = $(this).attr("data-postid");    

    $connection.invoke("SetLike", userId, postId).catch(function (err) {
        return console.error(err.toString());
    });
    event.preventDefault();
});

LikeHub.cs

public class LikeHub : Hub
{
    private readonly MyContext _ctx;
    public LikeHub (MyContext context)
    {
        _ctx = context;
    }

    public async Task SetLike(int userId, int postId)
    {
        Likes l = new Likes();
        Likes temp = _ctx.Likes.Where(x => x.PostId == postId && x.UserId == userId).FirstOrDefault();

        if(temp != null)
        {
            _ctx.Likes.Remove(temp);
        }
        else
        {
            _ctx.Likes.Add(l);

            l.UserId = userId;
            l.PostId = postId;
        }

        _ctx.SaveChanges();

        int numOfLikes= _ctx.Likes.Where(x => x.PostId == postId).Count();

        await Clients.All.SendAsync("ReceiveMessage", numOfLikes, postId);
    }
}

您可以通过

识别当前用户(点击 like button 的用户)

var userId = $(this).attr("data-userid");(就像有人点击 like button 时所做的那样)。

但问题是,当 SetLike 成功时(在 on ReceiveMessage javascript 函数内),您没有检查 userId

所以要解决这个问题,您需要将单击 like button 的用户的 userId 从后端发送到前端(到 on("ReceiveMessage"..) 函数)

例如:await Clients.All.SendAsync("ReceiveMessage", numOfLikes, postId, userId);

并在 ReciveMessage 上检查您从后端获得的 userId 是否与正在浏览 var currentUserId = $(this).attr("data-userid");

的当前用户匹配

如果它们相等则给 like button 上色,否则只更新 like counter.

这种方式可以解决您的问题。


另一种解决方案是发送 2 个请求,一个特定于单击 like button 的用户,另一个是向所有人发送更新 the like counter.