每次单击按钮时使用 ajax 从 DataObject 加载一定数量的项目?

Using ajax to load a certain number of items from a DataObject each time a button is clicked?

我有一个 See more 按钮,当我点击它时,我希望能够将另外 3 个过去的事件加载到页面加载时显示的默认 3 个过去的事件中,然后如果再次单击,添加另外 3 个等等.

下面的代码有效,但由于某种原因正在乘以数字,例如,如果我按代码现在的 "See more" 按钮,它应该 returns 18 past events只有 return 6 past events...

如果我 dd($amountOfCurrentPastEvents + 3) 我得到 int(6) returned 3 次,6 x 3 = 18。例如:

问题是为什么它被调用了三次?我在这里做错了什么?

DashboardPage.php

class DashboardPage_Controller extends Page_Controller {

    private static $allowed_actions = array(
        'pastEvent',
        'seeMorePastEvents',
        'pasteventfilter',
        'LimitedPastEvents'
    );

    public function LimitedPastEvents()
    {
        return PastEvent::get()->limit(3);
    }

    public function seeMorePastEvents() {
        if (Director::is_ajax()) {
            // Gets the amount of past events that are display on the page at present
            $amountOfCurrentPastEvents = $_POST['events'];
            // Adds 3 onto how ever many past events are currently showing
            $PastEvents = PastEvent::get()->limit($amountOfCurrentPastEvents + 3);
            return $this->customise(array(
                'Results' => $PastEvents
            ))->renderWith('AjaxPastEvents');

        }
    }

    ...

}

DashboardPage.ss

<% loop LimitedPastEvents %>
    <div class="past-event-results">
        <div class="col-md-4 no-padding past-event">
            <a href="$Link">
                <div class="live-workouts-wrapper">
                    <div class="on-demand-image" style="background-image: url($ThemeDir/images/vid-3.jpg);">
                        <div class="play-icon"></div>
                    </div>
                    <div class="on-demand-info text-center">
                        <div class="on-demand-location">
                            <span class="pin-icon"></span><span>$BranchLocation.Name, $BranchLocation.City</span>
                        </div>
                        <div class="on-demand-date-time">
                            <span class="time-icon"></span>
                            <span>{$EventDate.Day} {$EventDate.ShortMonth} {$EventDate.Format(dS)} $Time.Nice</span>
                        </div>
                        <div>
                            <strong>$EventName</strong>
                        </div>
                    </div>
                </div>
            </a>
        </div>
    </div>
<% end_loop %>

<div class="col-md-12">
    <div class="text-center">
        <button class="btn btn-seemore">SEE MORE<b class="btn-icon btn-down"></b></button>
    </div>
</div>

jQuery - 位于 DashboardPage.ss

<script>
$(document).ready(function() {
    var pastEventCount;
    $('.btn-seemore').on('click', function(event) {
        event.preventDefault();
        // Gets the amount of past events that are currently displayed on the page
        pastEventCount = $('.past-event').length;
        console.log(pastEventCount);
        $.post('/dashboard/seeMorePastEvents', {events: pastEventCount}, function(data) {
            $('.past-event-results').html(data);
        });
    });
});
</script>

问题是代码使用 $('.past-event-results').html(data); 将新内容添加到 .past-event-results,但模板开头有 3 .past-event-results div。

return由 ajax 函数编辑的数据(6 个 PastEvent 条目)添加到 3 div 秒,使结果显示 18 个项目。

以下循环创建 3 past-event-results divs 开头:

<% loop LimitedPastEvents %>
    <div class="past-event-results">
    ...
    </div>
<% end_loop %>

您可能希望将此 div 置于循环之外:

<div class="past-event-results">
<% loop LimitedPastEvents %>
    ...
<% end_loop %>
</div>

这意味着只有一个 past-event-results div.

我还建议将 seeMorePastEvents() 函数更改为仅 return 新项目,而不是每次都将所有现有项目加上新项目。这将节省需要传回的数据并略微改进服务器获取。

要进行此更改,我们首先需要将限制功能更改为仅获取 3 个项目并从 $amountOfCurrentPastEvents 点开始获取。

$PastEvents = PastEvent::get()->limit(3, $amountOfCurrentPastEvents);

DataListlimit()函数可以取2 parameters:

limit(integer $limit, integer $offset = 0)

我们使用偏移量来改变抓取起点。

然后我们更改 JavaScript 以附加检索到的数据而不是覆盖现有事件:

$('.past-event-results').append(data);

乍一看像是 JS 问题。

您可能发送了 x3 AJAX 个请求 - 如果您打开浏览器的调试器,有多少 XHR 请求被发送到 SilverStripe?

同时检查生成的标记。我怀疑您的 JS 逻辑应该附加到 .past-event-results DOM 节点本身,而不是附加到其内容,这实际上是 jQuery html 方法为您所做的。