2013-02-26 4 views
14

Tôi đang cố gắng sử dụng pjax trên trang web của mình, điều đó có nghĩa là yêu cầu trang đầy đủ tôi sẽ hiển thị toàn bộ mẫu (đây là hành vi bình thường), nhưng trên yêu cầu pjax tôi muốn chỉ hiển thị một phần. Mẫu của tôi tất cả mở rộng một mẫu chính.Laravel: cách chỉ hiển thị một phần của mẫu?

Làm cách nào tôi có thể làm điều đó một cách thanh lịch nhất?

Trả lời

3

câu trả lời tốt nhất của tôi ngay bây giờ sẽ được nêu theo quan điểm của bạn mà nó chỉ phải mở rộng mẫu tổng thể (layout) nếu yêu cầu không được gọi thông qua AJAX:

@if(!Request::ajax()) 
    @extends('master.template') 
@endif 

Lưu ý, tuy nhiên, điều này giải pháp có thể không tốt nhất cho các mẫu cụ thể của bạn (tôi chỉ có thể đoán được). Bạn cần đảm bảo rằng mỗi mẫu/chế độ xem chỉ chứa những thứ không lặp lại, như thanh bên, v.v. Ví dụ: nếu bạn có khu vực nội dung cần được cập nhật với pjax thì chế độ xem của bạn chỉ nên chứa bất kỳ nội dung nào nên được thay đổi.

+0

Nó không hoàn hảo, nhưng nó khá gần. Nếu điều này hoạt động (chưa thử nó) và không có ai đi kèm với một giải pháp tốt hơn, tôi sẽ chấp nhận câu trả lời này. –

0

Bên trong hành động của bộ điều khiển của bạn, trở lại một cách rõ ràng xem phần bạn muốn render:

public function action_someajax() 
{ 
    ... 
    return View::make('mypartial', $data); 
} 

Điều này sẽ làm cho một phần thay vì bố trí của bộ điều khiển.

+0

Làm thế nào mà sẽ làm việc? Đó là (gần như) cách tôi sử dụng nó ngay bây giờ: 'return View :: make ('page', $ data);' và trang đó sau đó '@extends ('master')'. –

+0

@duality_ Bạn sẽ phải chỉ định mẫu của mình trong bộ điều khiển, không phải trong mỗi chế độ xem của bạn để tính năng này hoạt động. – Michelle

+0

Không được. Thiết kế mẫu mở rộng nào là vấn đề thiết kế, không phải vấn đề về mã/bộ điều khiển. Do đó, quyết định này nên được thực hiện trong quan điểm. –

9

Tại sao bạn không chỉ thay thế nội dung thực tế trong trang được hiển thị bằng phần tử div hoặc html?

Tôi làm điều này mọi lúc với jQuery. Tôi chỉ đơn giản là xây dựng trang ban đầu của tôi và gửi nội dung cho các khung nhìn của tôi để hiển thị các phần trong bố cục chính của tôi.

Giả sử tôi có cột điều hướng bên trái và sau đó là một bài viết ở cột bên phải. Người dùng nhấp vào một nút để hiển thị bài viết tiếp theo, vì vậy đó là những gì tôi muốn thay thế.

Đầu tiên xây dựng quan điểm ban đầu từ điều khiển của bạn

public function index() 
{ 
    $article = Article::first(); 
    Return View::make('homepage', compact('article')); 
} 

Bây giờ trong quan điểm của trang chủ của bạn

@extends('layouts.master') 

@section('leftNavigation') 
    @include('homepageLeftNavigation') 
@stop 

@section('article') 
    <div id="articleContent"> 
    @include('article') <!-- see below, you'll update this include with the js below --> 
    </div> 
@stop 

@section('script') 
@parent 
{{-- <script> --}} 
//in JQuery I would do something like this 
$('a.nextArticle').click(function(){ 
    var next = $('.nextArticle').attr("id"); 
    var next = next + 1; 
    $('#articleContent').load({{ URL::to('articles/' + next) }}; 
}); 
@stop 

Giả sử bạn đang sử dụng một bộ điều khiển vát bạn có thể sử dụng chức năng hiển thị() của bạn, nhưng nếu bạn chỉ muốn một lời trêu ghẹo trên trang chủ, bạn có thể dễ dàng tạo ra một chức năng mới cho điều đó là tốt.

Trong chương trình của bạn() hoặc newFunctionWhateverYouCallIt(), bạn chỉ có thể nhận được bài viết bởi id

Article::find($id); 

Sau đó gửi mà tắt để nhằm được trả lại.

return View::make('article'); 

Và cuối cùng lượt xem bài viết bạn gọi bao gồm khi bạn lần đầu tiên được xây dựng trang và một lần nữa sau khi cập nhật qua Jquery hoặc pjax

 {{ $article->title }} 
    {{ $article->body }} 
    {{ $article->date }} 
    <a href="#" class="nextArticle" id="{{ $article->id }}">Next Article ></a> 

Xin lưu ý tôi đã không kiểm tra mã này vì vậy tôi chắc chắn có một vài lỗi, nhưng bạn có ý tưởng chung về logic để cập nhật một phần của trang của bạn.

30

Đây là một câu hỏi cũ nhưng tôi muốn đưa ra một giải pháp khác.

phép nói rằng bạn có một layout view gọi main.blade.php và một quan điểm cho rằng mở rộng chính gọi page.blade.php

main.blade.php

<!DOCTYPE html> 
<html lang="en-GB"> 
<head> 
    <title>My Title</title> 

    @section('head') 
     <link rel="stylesheet" href="{{ URL::asset('css/style.css') }}"> 
    @show 
</head> 
<body> 

    @yield('content') 

    @section('footer') 
     <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> 
     <script type="text/javascript" src="{{ URL::asset('js/main.js') }}"></script> 
    @show 
</body> 
</html> 

page.blade.php

@extends('main') 

@section('content') 
    <div class="container"> 
     This is a rendered page 
    </div> 
@stop 

Chỉ cần một mẫu đơn giản cơ bản để có được mọi thứ bắt đầu. Trong bộ điều khiển của bạn nếu bạn trả lại một View::make('page'), bạn sẽ nhận được HTML hoàn chỉnh nhưng Laravel cung cấp một cách để trả về các phần cụ thể. Dưới đây là một ví dụ về cách hiển thị nội dung bạn muốn dựa trên nếu nó một cuộc gọi ajax hay không từ bên trong điều khiển của bạn:

my_controller.php

function get_index() { 
    $view = View::make('page'); 

    if(Request::ajax()) { 
     $sections = $view->renderSections(); // returns an associative array of 'content', 'head' and 'footer' 

     return $sections['content']; // this will only return whats in the content section 

    } 

    // just a regular request so return the whole view 

    return $view; 
} 

Bây giờ khi bạn thực hiện một ajax gọi tới trang nó sẽ chỉ trả về phần nội dung chứ không phải toàn bộ HTML.

+0

+1 cho 'renderSections()' – Inigo

+0

Đây phải là câu trả lời được chấp nhận, IMO. – Inigo

+0

@Inigo Tôi chỉ xem xét lại điều này và quyết định rằng cách tôi đã có nó trước đó là một chút cẩu thả trong việc kiểm tra của nó. Vì vậy, chỉnh sửa phần yêu cầu. – JoeMoe1984