Laravel 4 - 使用 Ajax 更新 Div

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22135706/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 09:07:38  来源:igfitidea点击:

Laravel 4 - Update Div Using Ajax

ajaxlaravel

提问by DroBuddy

I'm using Laravel 4 and am trying to update a (#articles) div with the new articles that are retrieved from an ajax request. When I inspect the page and view the Network section, I can see the POST requests being fired off and it's not showing any errors (eg, articles appear to be returned). However, unfortunately, the #articlesdiv is not being updated with the new information. Yet, if I do a browser refresh, the new articles are displayed.

我正在使用 Laravel 4 并尝试使用从 ajax 请求中检索到的新文章更新 (#articles) div。当我检查页面并查看网络部分时,我可以看到 POST 请求被触发并且没有显示任何错误(例如,文章似乎被返回)。但是,不幸的是,该#articlesdiv 并未使用新信息进行更新。但是,如果我刷新浏览器,则会显示新文章。

Routes.php

路由.php

Route::any("/dashboard/latest_sa", [
    "as"    => "dashboard/latest_sa",
    "uses"  => "DashboardController@latest_sa"
]);

controllers/DashboardController.php

控制器/DashboardController.php

Class DashboardController extends \BaseController
{
...
   protected function latest_sa()
    {
      if( Request::ajax() )
      {
        // called via ajax
        $articles = Articles::orderBy('published_at', 'desc')->paginate(20);
        return json_decode($articles);
      } 
      else 
      {
        // fresh page load
        $articles = Articles::orderBy('published_at', 'desc')->paginate(20);
        return $articles;
      }
  }
...
}

app/views/dashboard/default.blade.php

应用程序/视图/仪表板/default.blade.php

...

@section("content")

// defined in /public/js/main.js
<script type="text/javascript">
    callServer();
</script>

<div class="col-xs-4 col-sm-4 col-md-4 col-lg-4">

    <h4>Latest Articles</h4>

    <div class="articles">
        <ul>
        @foreach ($articles as $article)
            <li>
                <img src="{{ $article->user_image }}" alt="{{ $article->article_title }}" />
                <a href="{{ $article->article_link }}">{{ $article->article_title }}</a>
                <div class="details">
                    <span class="author">{{ $article->author_name }}</span>
                    <span class="created">{{ Helpers::time_ago($article->published_at) }}</span>
                    <span class="symbol"><a href ="{{ $article->symbol_link }}">{{ $article->symbol_title }}</a></span>
                </div>
            </li>
        @endforeach
        </ul>
    </div>
    {{ $articles->links() }}
</div>

...

/public/js/main.js

/public/js/main.js

function callServer()
{
    setInterval(function(){
        $.ajax({
            type: "POST",
            url: "dashboard/latest_sa",
            success:function(articles)
            {
                $(".articles").html(articles);
            }
        });
    },5000);
}

JS is hardly my strong suit, so I'm not sure what I'm doing wrong here.

JS 不是我的强项,所以我不确定我在这里做错了什么。

And, for clarity sake, the reason why I'm trying to update all of the articles in the div is so that the Helpers::time_agomethod also gets called, instead of just fetching the new articles. This way, it properly shows how long ago the article was published (eg, less than a minute ago, a minute ago, a hour ago, a day ago, etc) without refreshing the page. Essentially, I'm trying to kill two birds with one stone; update the div with the most recent articles, and update the remaining article's published_atattribute using my Helpers::time_ago method. If there is a more effective / efficient way of doing this, feel free to correct me. This seems rather crude, but since it's only for personal use and will never be used for commercial purposes, it suits my needs (not that that excuses bad code).

而且,为了清楚起见,我尝试更新 div 中所有文章的原因是为了Helpers::time_ago调用该方法,而不仅仅是获取新文章。这样,它在不刷新页面的情况下正确地显示文章发表多长时间前(例如,不到一分钟前、一分钟前、一小时前、一天前等)。本质上,我试图用一颗石头杀死两只鸟;用最新的文章更新 div,并published_at使用我的 Helpers::time_ago 方法更新剩余文章的属性。如果有更有效/高效的方法来做到这一点,请随时纠正我。这看起来相当粗糙,但由于它仅供个人使用,绝不会用于商业目的,因此它符合我的需求(并不是说代码不好的借口)。

Nonetheless, from my fairly basic understanding, the JS should be doing the following steps:

尽管如此,根据我相当基本的理解,JS 应该执行以下步骤:

1) Fire a POST request off to the /dashboard/latest_saroute

1) 向/dashboard/latest_sa路由发出 POST 请求

2) Execute the DashboardController@latest_saaction

2)执行DashboardController@latest_sa动作

3) Return a DB collection of all $articlesordered by the latest published date, and paginated

3) 返回所有$articles按最新发布日期排序的数据库集合,并分页

4) Pass the $articlescollection back to the JS successattribute (as articles)

4) 将$articles集合传递回 JSsuccess属性 (as articles)

5) Fire the anonymous function, with the articlescollection as an argument

5) 以articles集合作为参数触发匿名函数

6) Update the corresponding inner HTML with the results from the articlescollection

6) 使用articles集合中的结果更新相应的内部 HTML

The logic sounds right, so I'm pretty sure this is going to be a human error (98% of the time it is, after all. lol). Hopefully, someone here will be able to see the (probably glaring) problem in the logic and point me in the right direction.

这个逻辑听起来是对的,所以我很确定这将是一个人为错误(毕竟 98% 的情况是这样。哈哈)。希望这里的某个人能够看到逻辑中的(可能是明显的)问题,并为我指明正确的方向。

In the meantime, I'm going to keep toying around with it.

与此同时,我将继续玩弄它。

I look forward to your thoughts, ideas, and suggestions. TIA.

我期待着您的想法、想法和建议。TIA。



EDIT:

编辑:

Well, I found one of the problems; the articles div is a class, and in the JS I'm referring to it as an id. I fixed that, and now after the timeInterval, the article's div is "updated" but no results are being displayed (none, zippo, nadda).

好吧,我发现了其中一个问题;文章 div 是一个类,在 JS 中我将其称为 id。我解决了这个问题,现在在 timeInterval 之后,文章的 div 被“更新”,但没有显示任何结果(无、zippo、nadda)。

Yet, if I directly access the /dashboard/latest_saURI I get the valid JSON response that I'm expecting. So, albeit I am closer, I am still missing something.

然而,如果我直接访问/dashboard/latest_saURI,我会得到我期望的有效 JSON 响应。所以,尽管我更接近了,但我仍然缺少一些东西。



EDIT 2:

编辑2:

Okay, in the controller, I made some changes which can be seen above, where I am now doing a json_decode on the $articles, before returning them to be passed into the view. With that in place, the articles are showing back up again after the timeInterval has elapsed, however, the new articles and the published_atfor the existing articles are not being updated. After reviewing Inspect -> Network, it shows that the server is responding with a 500 Internal Server Error from the ajax POST request.

好的,在控制器中,我做了一些可以在上面看到的更改,我现在在 $articles 上执行 json_decode,然后将它们返回以传递到视图中。有了这个,文章会在 timeInterval 过去后再次显示,但是,新文章和published_at现有文章不会更新。查看 Inspect -> Network 后,它显示服务器正在响应来自 ajax POST 请求的 500 Internal Server Error。

Hrm... Seems like I'm going in circles. Sounds like a good time to take a break and go for a walk. ;)

嗯……看来我要绕圈子了。听起来是休息和散步的好时机。;)



EDIT 3:

编辑 3:

Well, I modified my Helpers class and added in the following method to check if the $articleis a json object.

好吧,我修改了我的 Helpers 类并添加了以下方法来检查它是否$article是一个 json 对象。

public static function isJson($string)
{
    json_decode($string);
    return (json_last_error() == JSON_ERROR_NONE);
}

app/views/dashboard/index.blade.php

应用程序/视图/仪表板/index.blade.php

@foreach ($articles as $article)
    <?php
        if( Helpers::isJson($article) )
        {
            $article = json_decode($article);
            // dd($article) // when uncommented it returns a valid PHP object 
        }
    ?>
    <!-- Iterate over the article object and output the data as shown above... -->
@endforeach

As you can see, (for the time being) inside of my view's foreach($articles as $article), I run Helpers::isJson($article) as a test and decode the object if it is json. This has enabled me to get passed the 500 Internal Server Error message, populate the articles div with the results on the initial load, and after the ajax POST request is fired off, I'm getting back a server response of 200 OKaccording to Inspect -> Network. However, after it updates the div, it doesn't show any articles.

如您所见,(暂时)在我的视图中foreach($articles as $article),我运行 Helpers::isJson($article) 作为测试并解码对象(如果它是 json)。这使我能够通过 500 Internal Server Error 消息,在初始加载时使用结果填充文章 div,并且在 ajax POST 请求被触发后,我200 OK根据 Inspect返回服务器响应->网络。但是,在更新 div 后,它不显示任何文章。

Around, and around I go... I think it's time I take that break I keep murmuring about. ;)

绕来绕去……我想是时候休息一下了,我一直在抱怨。;)

Any thoughts, suggestions and / or ideas are greatly welcomed and appreciated.

任何想法、建议和/或想法都非常受欢迎和赞赏。

采纳答案by The Alpha

At first, you should know that, when you return a collection from the controller/route, the response automatically turns in to a jsonresponse so, you don't need to use json_decode()and it won't work, instead, you may try something like this (from your controller for ajax):

首先,你应该知道,当你从控制器/路由返回一个集合时,响应会自动变成json响应,所以你不需要使用json_decode()它也不会工作,相反,你可以尝试类似的东西这(来自您的 ajax 控制器):

$articles = Articles::orderBy('published_at', 'desc')->paginate(20);
return View::make('defaultAjax')->with('articles', $articles);

Since building the HTMLin the client side using the jsondata received from server side would be tough for you so, you may return HTMLfrom the server with the generated view instead of json, so you may try something like this in your successhandler:

由于HTML使用json从服务器端接收到的数据在客户端构建对您来说很困难,因此您可以HTML使用生成的视图而不是从服务器返回json,因此您可以在success处理程序中尝试这样的事情:

success:function(articles) {
    $(".articles").html(articles);
}

Now create a view for ajaxresponse without extending the template like this:

现在为ajax响应创建一个视图,而不像这样扩展模板:

//defaultAjax.blade.php used in the controller for ajax response

<ul>
    @foreach ($articles as $article)
        <li>
            <img src="{{ $article->user_image }}" alt="{{ $article->article_title }}" />
            <a href="{{ $article->article_link }}">{{ $article->article_title }}</a>
            <div class="details">
                <span class="author">{{ $article->author_name }}</span>
                <span class="created">{{ Helpers::time_ago($article->published_at) }}</span>
                <span class="symbol"><a href ="{{ $article->symbol_link }}">{{ $article->symbol_title }}</a></span>
            </div>
        </li>
    @endforeach
</ul>
{{ $articles->links() }}

Notice, there is no @extendds()or @section(), just plain partial view, so it'll be rendered without the template and you can insert the ulinside the .articlesdiv. That's it.

请注意,没有@extendds()or @section(),只是普通的部分视图,因此它将在没有模板的情况下呈现,您可以ul.articlesdiv内部插入。就是这样。

回答by user3373249

$("#articles").html(articles); ->> $(".articles").html(articles);