Laravel View Composer - 当 include 一个模板时,自动获取其所需的变量
网站中,许多页面的侧边栏是相同的。例如:
分类列表页,与文章详情页的侧边栏都包含
- 最新文章
- 最新评论
- 统计计数
这些相同的侧边栏数据也是动态的,并不是固定的。
在每个 controller 里都写一遍数据读取逻辑,并赋值给模板,这样做有几个弊端
- 重复编码量不小。即使提取成函数,也要手动将变量传递给模板,controller 中无法专注于业务逻辑
- 不利于模块化
简单粗暴的做法 - 全局 view share
之前,我用了一种简单粗暴的解决方案:
在 app/Providers/AppServiceProvider.php 里全局共享模板变量,即,View::share。
但是,这种做法的弊端是
- 及时某些页面不需要这些变量,也会浪费时间去获取一遍
- 代码越来越臃肿
View Composer - 当 include 一个 view 时,自动获取其所需的变量
Laravel 的 View Composer 很好的解决了这个问题。
官方文档: https://laravel.com/docs/5.5/views#view-composers
View composer 实际上是一个回调,当需要渲染一个指定 blade 模板时,被自动调用。
View Composer 需要在 service provider 中进行注册。即,新建一个 Service Provider, 然后加入到 config/app.php 中,方便 Laravel 启动时自动载入。
这个 view composer 可以偷懒地写在 AppServiceProvider.php 中,但是,带来的问题就是代码乱的一塌糊涂。还是放到独立的文件中比较好。
class based composers VS Closure based composers
class based composers
View::composer(
'profile', 'App\Http\ViewComposers\ProfileComposer'
);
Closure based composers
View::composer('dashboard', function ($view) {
//
});
我更倾向于使用 Closure based composers,这样做的好处有
- 省去新建一个 composer 文件。因为如果没有复用、没有解耦的需求,新建一个代码文件是件我无法理解的事情
- 逻辑一目了然,不需要再切到另外一个文件查看
如果通过 $view->with 给一个模板传递多个变量
// 一个变量
$view->with('count', 1);
// 多个变量
$view->with('count', 1)
->with(‘site’, ‘sunzhongwei.com’);
如何通过 laravel 命令创建 View Composer 文件
View composer 统一放到目录
app/Http/ViewComposers
下。
Laravel 内置的命令
make:provider Create a new service provider class
即
php artisan make:provider SidebarCompoerServiceProvider
为何用这么长的名字?因为可以在 provider 列表里一目了然。
app/Providers/SidebarCompoerServiceProvider.php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class SidebarCompoerServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* @return void
*/
public function boot()
{
// View::composer
}
/**
* Register the application services.
*
* @return void
*/
public function register()
{
//
}
}
将该文件从 app/Providers 移动到 app/Http/ViewComposers 目录下。
添加 service provider 到 config.php 中
参考 AppServiceProvider 的做法
App\Providers\AppServiceProvider::class,
一个 View Composer 给多个 blade 模板提供数据
View::composer(
['profile', 'dashboard'],
'App\Http\ViewComposers\MyViewComposer'
);
当然也可以使用星号为所有模板提供数据 (严重不推荐, 这跟之前的 app service provider 中的做法没有本质区别)
Laravel Service Provider 是什么?
https://oomusou.io/laravel/laravel-service-provider/
我发现很难理解 Laravel Service Provider 的概念。
先从最常见的使用场景来看:
我们安装一个新的 Laravel 包,总是先 composer install xxx,然后修改 config/app.php 文件,在 providers 里加入 XXX::class 。
疑问来了,composer install 之后为何还要手动配置 provider.
因为,composer install 只是将三方包的代码安装到 vendor 目录下。
但是,Laravel 并不知道这个三方包的存在,如果想让 laravel 启动时自动加载这个三方包,就需要在 config/app.php 的 providers 中加入这个包。
所以,service provider 存在的意义就是方便管理哪些模块应该在 laravel 启动时自动载入的了?
Register 和 Boot 的使用,我还是看不懂?
一个完整的例子
创建 View Composer Service Provider
php artisan make:provider SidebarCompoerServiceProvider
mkdir app/Http/ViewComposers
mv app/Providers/SidebarComposerServiceProvider.php app/Http/ViewComposers/
代码填充如下
<?php
namespace App\Http\ViewComposers; // 注意修改 namespace
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\View;
use App\Models\WebExamInfo;
use App\Models\Live;
class SidebarComposerServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* @return void
*/
public function boot()
{
View::composer('detail_sidebar', function ($view) {
// 招考信息
$exams = WebExamInfo::orderBy('id', 'desc')
->limit(6)
->get();
// 直播信息
$lives = Live::where('is_deleted', 0)
->orderBy('id', 'desc')
->limit(6)
->get();
$view->with('exams', $exams)
->with('lives', $lives);
});
}
/**
* Register the application services.
*
* @return void
*/
public function register()
{
//
}
}
最后在 config/app.php 的 providers 中添加
App\Http\ViewComposers\SidebarComposerServiceProvider::class,
对应的修改 blade 渲染逻辑即可。
Laravel View Composer - 当 include 一个模板时,自动获取其所需的变量的更多相关文章
- zTree异步生成数据时无法获取到子节点的选中状态
最近在项目中遇到一个问题,需求如下: 根据选中不同的人员(ID)向后台发送ajax请求,通过返回的数据来生成该人员的权限访问树,该树目录最少为3级目录,在生成的时候会自动勾选上次保存过的选中状态,点击 ...
- VMware vSphere 服务器虚拟化之二十二桌面虚拟化之创建View Composer链接克隆的虚拟桌面池
VMware vSphere 服务器虚拟化之二十二桌面虚拟化之创建View Composer链接克隆的虚拟桌面池 在上一节我们创建了完整克隆的自动专有桌面池,在创建过程比较缓慢,这次我们将学习创建Vi ...
- win7,Mindmanager2012使用模板时弹出Runtime error R6025解决方法
Mindjet.MindManager2012.v10.0在应用个别模板时提示"参数错误",然后自动关闭. 解决办法: 如果是win7系统,可以进入C:\Users\(用户名)\A ...
- iOS开发UI篇—使用picker View控件完成一个简单的选餐应用
iOS开发UI篇—使用picker View控件完成一个简单的选餐应用 一.实现效果 说明:点击随机按钮,能够自动选取,下方数据自动刷新. 二.实现思路 1.picker view的有默认高度为162 ...
- php包含(include/require)文件时的作用域
当一个php脚本被require/include时,他的变量作用域根据其上下文环境决定. 1.如果是在一个函数中require/include一个文件,则此文件中的变量作用域是这个函数的范围.也就是说 ...
- listview当选中某一个item时设置背景色其他的不变
listview当选中某一个item时设置背景色其他的不变: 可以使用listview.setOnFoucsChangeListener(listener) ; /** * listview获得焦点和 ...
- VMware vSphere 服务器虚拟化之十八桌面虚拟化之安装View Composer服务器
VMware vSphere 服务器虚拟化之十八桌面虚拟化之安装View Composer服务器 View Compose服务可安装在管理虚拟机的vC ...
- thinkphp 使每一个模板页都包括一个header文件和一个footer文件
在开发的过程中,常常遇到要使每一个模板页都包括一个header文件和一个footer文件.thinkPHP的模板布局为我们提供了一个叫全局配置方式可以解决问题. 1. 在配置文件里开启LAYOUT_O ...
- FreeMarker 语法 include 引用模板
一.java 代码 @Test public void testFreeMarker() throws Exception { //1.创建一个模板文件 //2.创建一个Configuration对象 ...
随机推荐
- 关于mysql数据库优化
关于mysql数据库优化 以我之愚见,数据库的优化在于优化存储和查询速度 目前主要的优化我认为是优化查询速度,查询速度快了,提高了用户的体验 我认为优化主要从两方面进行考虑, 优化数据库对象, 优化s ...
- Java 搜索引擎
1.Java 全文搜索引擎框架 Lucene 毫无疑问,Lucene是目前最受欢迎的Java全文搜索框架,准确地说,它是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎.Luc ...
- GCC输出带C源代码的汇编文件
GCC输出带C源代码的汇编文件,一共有两种方式(同样也适合G++输出呆CPP源代码的汇编文件). 测试代码(hello.cpp) #include<iostream> usingnames ...
- Problems you may meet
一.正确安装sklearn却提示No module named 'sklearn.lda' It seems that you have installed a newer version of sk ...
- Unity5天空盒小黑点问题
unity5打开的时候有时候天空盒基本上全是小黑点,原因我现在不知道,以后再补充. 解决办法: 打开windows--lighting选项.然后双击skybox里面的材质,右边会显示当前天空盒的材质界 ...
- Jmeter调用 Json接口测试之关键点申明Content-Type类型
背景: 最近,在做接口测试发现创建运单接口,通过普通表单请求总是失败,开始我以为是后端接口出现问题,但通过前端页面都能创建运单,F12打开浏览器开发者模式,获取该接口请求入参发现,请求的数据格式是js ...
- WIN10下安装USB转串口驱动出现“文件的哈希值不在指定的目录”的解决办法
今天安装openJTAG驱动时出现“文件的哈希值不在指定的目录”,系统为WIN10专业版. 原因是驱动无数字签名,在WIN10中是不安全的驱动,所以显示哈希值不在范围内不能安装. 经查阅已经解决,发放 ...
- JavaScript之复杂对象的深拷贝(完全深拷贝)
由于网上很多的深拷贝大都有如下问题: 1.灵活性.不能应对复杂对象(复杂对象是指:单一数组对象.多数组对象.多非数组对象.单一对象组合形成的复杂对象)的灵活拷贝 2.不变性.即 拷贝的对象与原对象的结 ...
- Linux之更改Nginx映射默认根目录
更改nginx映射默认根目录: 1.打开默认配置文件:sudo vi /etc/nginx/sites-available/default 2.修改配置:root /var/www/html/xx ...
- POJ3436 ACM Computer Factory【EK算法】
题意: 每个电脑需要P个组成部分,现有N的机器,每个机器都可以对电脑进行加工,不过加工的前提是某些部分已经存在,加工后会增加某些部分.且在单位时间内,每个机器的加工都有一个最大加工容量,求能得到的最大 ...