2017-07-12 27 views
7

Trên trang web của tôi, người dùng có thể đăng "trạng thái" và những người dùng khác có thể trả lời/nhận xét về các trạng thái đó. Ví dụ: trên trang đầu của trang web của tôi, tôi có trạng thái được thích nhiều nhất trong 3 ngày qua được hiển thị.Tải thêm eloquent có nhiều truy vấn quan hệ thông qua ajax trong Laravel?

Trong tôi HomeController.php:

$statuses = Status::where('is_image', 1) 
    ->where('is_mature', 0) 
    ->where('created_at', '>=', Carbon::now()->subHours(168)) 
    ->orderBy('like_count', 'desc') 
    ->take(6) 
    ->get(); 

Trạng thái có cũng có thể trả lời. Trả lời sử dụng cùng một bảng như bảng trạng thái. Trả lời là khá nhiều trạng thái với trạng thái "gốc" và trạng thái thông thường chỉ là trạng thái không có "cha mẹ".

Từ mô hình status.php:

public function scopeNotReply($query) { 
    return $query->whereNull('parent_id'); 
} 

public function replies() { 
    return $this->hasMany('CommendMe\Models\Status', 'parent_id'); 
} 

Vì vậy, trở lại trang chủ của tôi, đây là cách các trạng thái được nạp trên trang chủ:

home.blade.php:

@if ($statuses->count()) 
    @foreach ($statuses as $status) 
     <div class="post-container"> 

     ... 

     blah blah blah 

     ... 

     @foreach ($status->replies->reverse()->slice(0, 3) as $reply) 
      <div class="status-reply-content"> 
       ... 

       blah blah blah 

       ... 
      </div> 
     @endforeach 

     @if (count($status->replies) > 3) 
      <a href="#"> 
        View More Comments ({{ count($status->replies) }}) 
      </a> 
     @endif 

     </div> 
    @endforeach 
@endif 

Điều tôi muốn dành cho nút "Xem thêm nhận xét" để tải một bộ 3 nhận xét khác.

Điều này sẽ đơn giản nếu chúng được phân trang. Trong thực tế, ở nơi khác trên trang web của tôi, tôi tải thêm hình ảnh thông qua ajax. Giống như vậy:

if($request->ajax()) { 
    return [ 
     'images' => view('browse.partials.fullview_partial')->with('images', $images->appends(request()->only('query')))->render(), 
     'next_page' => $images->nextPageUrl() 
    ]; 
}  

tuy nhiên điều này phụ thuộc vào tải trong tập hợp trang tiếp theo thông qua ajax. Trong khi mối quan hệ $status->replies không được phân trang.

Vậy làm cách nào để tải thêm câu trả lời trong trường hợp này?

Chỉnh sửa:

Ngay cả giải pháp thay thế cũng sẽ hữu ích.

+0

có vẻ như điều này sẽ đơn giản hơn và hợp lý hơn nếu trạng thái và câu trả lời được lưu trữ trong các bảng riêng biệt. Lý do cho * không * làm điều đó là gì? Tôi có nghĩa là, một "trả lời" sẽ không bao giờ là một "trạng thái" mà không có cha mẹ của nó vậy tại sao lưu trữ chúng lại với nhau? – DelightedD0D

+0

Tôi thực sự không muốn làm điều đó vào thời điểm này. Đó sẽ là phương sách cuối cùng. –

+0

Hơn nữa, ngay cả khi tôi đã tạo bảng trả lời, tôi không thấy cách tôi có thể phân trang các câu trả lời, trừ khi bạn có thể có phân trang lồng nhau trong Laravel? –

Trả lời

2

Những gì tôi đã làm chỉ đơn giản là tạo một hàm mới trong bộ điều khiển cho chính yêu cầu đó, sau đó gửi ID của trạng thái cùng với nó, cùng với số lượng bỏ qua (tăng được nạp) để bỏ qua các câu trả lời đã tải.

public function getReplies($statusID, $skip, Request $request) { 

    $status = Status::findOrFail($statusID); 
    $replies = $status->replies()->orderBy('created_at', 'desc')->skip($skip)->take(10)->get(); 

    if($request->ajax()) { 
     return [ 
      'replies' => view('templates.partials.replies')->with('replies', $replies)->render(), 
     ]; 
    } 
} 
+1

Đặt DB truy vấn bên trong khối 'nếu AJAX'. – Tpojka

5

Bạn có cần tải trang trả lời đầu tiên phía máy chủ không? Tôi đoán vì bạn sẵn sàng tải các trang tiếp theo bằng AJAX, bạn chỉ có thể xử lý tất cả phía máy khách và chỉ có một điểm cuối AJAX cung cấp dữ liệu.

Chỉ cần thực hiện cuộc gọi ajax đến điểm cuối của bạn, chuyển id trạng thái và số trang.

// AjaxController 
public function replies() 
{ 
    $status = Status::findOrFail(request('id')); 
    return $status->replies()->paginate(3); 
} 

(Số trang sẽ được giải quyết tự động.)

này sẽ trả về một đại diện JSON của paginator, trong đó có các url cho các trang trước và sau, và các dữ liệu cho trang hiện tại. Sau đó, chỉ hiển thị phía máy khách dữ liệu.

+0

Câu trả lời của bạn giống với câu trả lời của tôi. Cảm ơn bạn đã trả lời! –

Các vấn đề liên quan