【问题标题】:Add like on click点击添加喜欢
【发布时间】:2023-03-25 12:20:03
【问题描述】:

我需要创建一个带有当前时间的cookie方法,它会首先检查数据(like_fingerarticle_id),如果没有数据,则添加一个like并更新日期,如果有数据,然后什么都不做。

我有一个function

$likes = request()->cookie('like_finger');
$hours = 24;
if ($likes) {
    Article::find($id)
    ->where('updated_at', '<', Carbon::now()->subHours($hours)->toDateTimeString())
    ->increment('like_finger');
}

但我还不能检查它,因为我对添加喜欢按钮感到困惑

我在 php.blade 中添加了一个按钮,并在 js 中创建了一个函数

<input type="button" id="start" value="Like Finger" onclick="startCombine(this)"> {{ $article->like_finger }}
function startCombine(startButton) {
    startButton.disabled = true;
    startButton.disabled = false;
}

我如何确保在为真时添加了喜欢?

我希望在点击按钮的时候添加一个like,它会在cookies中存储24小时,我写了一个大概应该如何添加like的函数,但并不完美,因为没有按钮功能

【问题讨论】:

  • 显然您使用的是模板引擎。是树枝吗?
  • 也许这里有一些对你有帮助的东西:stackoverflow.com/questions/35737442/…
  • @LajosArpad 不,我不使用
  • @Kim2000 有些部分强烈表明使用了模板引擎,即{{ $article-&gt;like_finger }}。那么,你如何构建你的观点呢?
  • 我认为你正在使用 Blade

标签: javascript ajax laravel laravel-blade


【解决方案1】:

首先,您不应该在客户端存储任何逻辑。使用 Laravel Aquantances 包是这种功能的一个很好的替代方案。

https://laravel-news.com/manage-friendships-likes-and-more-with-the-acquaintances-laravel-package

无论如何,既然你想用 cookie 来做;

我们实际上比想象的要容易得多。

Articles.php

class User extends Authenticatable
{
    // ...

    public static function hasLikedToday($articleId, string $type)
    {
        $articleLikesJson = \Cookie::get('article_likes', '{}');

        $articleLikes = json_decode($articleLikesJson, true);

        // Check if there are any likes for this article
        if (! array_key_exists($articleId, $articleLikes)) {
            return false;
        }

        // Check if there are any likes with the given type
        if (! array_key_exists($type, $articleLikes[$articleId])) {
            return false;
        }

        $likeDatetime = Carbon::createFromFormat('Y-m-d H:i:s', $articleLikes[$articleId][$type]);

        return ! $likeDatetime->addDay()->lt(now());
    }

    public static function setLikeCookie($articleId, string $type)
    {
        // Initialize the cookie default
        $articleLikesJson = \Cookie::get('article_likes', '[]');

        $articleLikes = json_decode($articleLikesJson, true);

        // Update the selected articles type
        $articleLikes[$articleId][$type] = today()->format('Y-m-d H:i:s');

        $articleLikesJson = json_encode($articleLikes);

        return cookie()->forever('article_likes', $articleLikesJson);
    }
}

上面的代码将允许我们在用户喜欢文章时生成我们想要设置的 cookie。

您需要关心几件重要的事情。

  • 不要忘记将 cookie 与响应一起发送。
  • 重定向回页面以使 cookie 生效。

我做了一个非常小的例子:

路由/web.php

Route::get('/test', function () {
    $articleLikesJson = \Cookie::get('article_likes', '{}');

    return view('test')->with([
        'articleLikesJson' => $articleLikesJson,
    ]);
});

Route::post('/test', function () {
    if ($like = request('like')) {
        $articleId = request('article_id');

        if (User::hasLikedToday($articleId, $like)) {
            return response()
                ->json([
                    'message' => 'You have already liked the Article #'.$articleId.' with '.$like.'.',
                ]);
        }

        $cookie = User::setLikeCookie($articleId, $like);

        return response()
            ->json([
                'message' => 'Liked the Article #'.$articleId.' with '.$like.'.',
                'cookie_json' => $cookie->getValue(),
            ])
            ->withCookie($cookie);
    }
});

资源/视图/test.blade.php

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <meta name="csrf-token" content="{{ csrf_token() }}" />
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css" integrity="sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l" crossorigin="anonymous">
</head>
<body>
    <div class="container">
        @if (session('success'))
            <div class="alert alert-success" role="alert">
                {{ session('success') }}
            </div>
        @endif

        <pre id="cookie-json">{{ $articleLikesJson }}</pre>

        <div class="row">
            @foreach (range(1, 4) as $i)
                <div class="col-3">
                    <div class="card">
                        <div class="card-header">
                            Article #{{  $i }}
                        </div>
                        <div class="card-body">
                            <h5 class="card-title">Special title treatment</h5>
                            <p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
                            <a href="/test?like=heart&article_id={{ $i }}" class="btn btn-primary like-button">
                                Like Heart
                            </a>
                            <a href="/test?like=finger&article_id={{ $i }}" class="btn btn-primary like-button">
                                Like Finger
                            </a>
                        </div>
                        <div class="card-footer text-muted">
                            2 days ago
                        </div>
                    </div>
                </div>
            @endforeach
        </div>
    </div>

    <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/js/bootstrap.min.js" integrity="sha384-+YQ4JLhjyBLPDQt//I+STsc9iw4uQqACwlvpslubQzn4u2UU2UFM80nGisd026JF" crossorigin="anonymous"></script>

    <script>
        $(function() {
            $.ajaxSetup({
                headers: {
                    'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
                }
            });

            $('.like-button').on('click', function(event) {
                event.preventDefault();

                let href = $(this).attr('href');

                $.ajax({
                    url: href,
                    type: 'POST',
                    success: function (response) {
                        alert(response.message)

                        $('#cookie-json').text(response.cookie_json)
                    }
                })
            });
        });
    </script>
</body>
</html>

【讨论】:

    【解决方案2】:

    在 Blade 中你可以有条件,比如

    @if (count($records) === 1)
        I have one record!
    @elseif (count($records) > 1)
        I have multiple records!
    @else
        I don't have any records!
    @endif
    

    示例取自https://laravel.com/docs/8.x/blade

    让我们尝试将其应用于您的特定问题

    @if ($article->article_id && $article->like_finger)
        <input type="button" id="start" value="Like Finger" onclick="startCombine(this)"> {{ $article->like_finger }}
    @endif
    

    【讨论】:

    • 谢谢,我现在去看看
    【解决方案3】:

    单击按钮时在 startCombine() 中发出 AJAX 请求。

    您的服务器代码处理 like 似乎使用了一个名为 like_finger 的 cookie,因此在向服务器发出请求之前,您需要创建该 cookie:

    const d = new Date();
    d.setTime(d.getTime() + (24*60*60*1000)); // Expiry in milliseconds
    document.cookie = "like_finger=" + d.toUTCString() + 
                      ";expires=" + d.toUTCString() + 
                      ";path=/";
    

    (使用上述值设置 cookie 在 24 小时后过期)

    然后你想把它发送到服务器:

    var xhttp = new XMLHttpRequest();
    xhttp.open("POST", "the_place_where_php_processing_code_is.php", true); 
    xhttp.setRequestHeader("Content-Type", "application/json");
    xhttp.onreadystatechange = function() { // When status of the ongoing request changes
        if (this.readyState == 4 && this.status == 200) {
             // Server has processed the like request and is done
             // You can do some "summary" here, like disabling the Like button
             var response = this.responseText;
        }
    };
    var data = {
        id : 1, // The id of the article being liked, not sure how to retrieve that right now
    };
    xhttp.send(JSON.stringify(data));
    

    ..然后你在服务器上接收 PHP 代码时使用这样的东西:

    $id = $request->input('id'); // $id = 1 (in this case, of course)
    

    【讨论】:

    • 我对ajax一点都不熟悉,请问如何发出请求,以及在哪里将这段代码插入到js文件中?
    • @Kim2000 js 代码应该在你的 startCombine() 方法中。 (第一个块首先设置cookie..)
    • 好的,我现在试试
    • 什么都没有发生
    • @Kim2000 应该。 jsfiddle.net/kjoq48ry
    猜你喜欢
    • 2016-11-09
    • 2021-05-29
    • 1970-01-01
    • 1970-01-01
    • 2016-08-30
    • 1970-01-01
    • 1970-01-01
    • 2017-06-07
    • 2011-12-19
    相关资源
    最近更新 更多