【发布时间】:2013-02-12 07:47:17
【问题描述】:
我正在尝试在我的网站上使用 pjax,这意味着对于整页请求,我会渲染整个模板(这是正常行为),但对于 pjax 请求,我只想渲染一个部分。我的模板都扩展了主模板。
我怎样才能最优雅地做到这一点?
【问题讨论】:
我正在尝试在我的网站上使用 pjax,这意味着对于整页请求,我会渲染整个模板(这是正常行为),但对于 pjax 请求,我只想渲染一个部分。我的模板都扩展了主模板。
我怎样才能最优雅地做到这一点?
【问题讨论】:
为什么不直接使用 div 或 html 元素替换呈现页面中的实际内容?
我一直使用 jQuery 来做这件事。我只是构建我的初始页面并将内容发送到在我的主布局中呈现部分的视图。
假设我有一个左侧导航栏,然后在右侧栏中有一篇文章。用户单击一个按钮以显示下一篇文章,这就是我要替换的内容。
首先从你的控制器构建初始视图
public function index()
{
$article = Article::first();
Return View::make('homepage', compact('article'));
}
现在在您的主页视图中
@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
假设您使用的是资源丰富的控制器,您可以使用 show() 函数,但如果您只想在主页上放一个预告片,您也可以轻松地为此创建一个新函数。
在您的 show() 或 newFunctionWhateverYouCallIt() 中,您可以通过 id 获取文章
Article::find($id);
然后将其发送到要渲染的视图。
return View::make('article');
最后,您调用的文章视图包括您第一次构建页面时以及通过 Jquery 或 pjax 更新后再次生成的页面
{{ $article->title }}
{{ $article->body }}
{{ $article->date }}
<a href="#" class="nextArticle" id="{{ $article->id }}">Next Article ></a>
请注意,我没有测试过这段代码,所以我确信有一些错误,但您对更新页面单个部分的逻辑有了大致的了解。
【讨论】:
这是一个老问题,但我想提出另一个解决方案。
假设您有一个名为 main.blade.php 的视图布局和另一个扩展 main 的视图,名为 page.blade.php em>
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
只需一个简单的基本模板即可开始。在您的控制器中,如果您返回 View::make('page'),您将获得完整的 HTML,但 Laravel 提供了一种返回特定部分的方法。下面是一个示例,说明如何根据是否来自控制器内部的 ajax 调用来显示您想要的内容:
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;
}
现在,当您对页面进行 ajax 调用时,它只会返回内容部分而不是整个 HTML。
【讨论】:
在控制器的操作中,显式返回要渲染的局部视图:
public function action_someajax()
{
...
return View::make('mypartial', $data);
}
这将呈现部分而不是控制器的布局。
【讨论】:
return View::make('page', $data); 和那个页面然后是@extends('master')。
我现在最好的答案是在您看来,如果请求不是通过 AJAX 调用,它只能扩展主模板(布局):
@if(!Request::ajax())
@extends('master.template')
@endif
但是,请注意,此解决方案可能不适合您的特定模板(我只能猜测)。您需要确保每个模板/视图仅包含不重复的内容,例如侧边栏等。例如,如果您有一个需要使用 pjax 更新的内容区域,那么您的视图应该只包含任何内容应该改。
【讨论】: