数据共享入口

前言

上一节,我们对标签的选择方面做了一些优化,使得标签的选择更加合理。这节我们学习如何定义数据共享入口 。

说明

开发环境:Windows 7
Laravel 版本: 5+
IDE: Phpstorm

现在我们的代码会出现一个现象,那就是对所有的 view 层,我们都会有一个来自 controller 的请求。如果是不同的业务逻辑,那也就罢了;如果是同一业务,同一数据,却被不同的 view 多次请求,有点不太合理。

问题的引出

首先,我们从 bootstrap 事例页中提取一下官方的导航栏代码

把上面这段代码复制 master.blade.php 的 body 标签里面的最上面。保存一下刷新浏览器看看效果,如果不太满意(比如导航条盖住了下面的正文),那你可以到 app.scss 里面修改一下样式表。

下面我们添加一个导航列与 Articles 并列,并且在最右边:

我们通过这个导航标签来获取最新的文章。通过link_to_action('ArticlesController@show',$latest->title,[$latest->id])可以大致猜出个一二,这个语句的意思就是要访问 ArticlesController 的 show 方法,然后返回 $latest 的对象,获取到该对象的 title 和 id 。

下面我们再去修改 ArticlesController.php 。 打开该文件,找到 index() 方法,修改成如下语句:

保存文件,刷新浏览器,可以看到导航栏的最右边变成了最新的文章的标题。

现在请看一个现象,当你在浏览器输入 localhost:8888/articles/create 或者在 articles 后面添加任何一个 ArticlesController 里存在的方法,回车后都是访问不到的。

为何?原因很简单,这就回到了题头说的问题的具体化体现。你导航栏的最右边是一个访问了数据库并获取到数据的行为,但是这个数据只作用到了该行为,并未给其他行为传送数据,一旦执行了其他行为,必然会报错。

问题的解决

你可以通过如下方式解决:

你可以给每个方法都修改成这样。方法少了还好说,方法多了怎么办,还手工添加吗,肯定不行。

推荐的方案

这就需要一个总的数据获取的入口,只要在入口获取到,其他的也可以用。

首先,目前的逻辑是这样的,导航栏的最右边需要访问数据库获取数据,而且,获取到的数据其他方法也要用到,对吧。所以,这个入口就应该定到导航栏,在导航栏加载的时候,我们就要获取到从数据库里得到的数据。

好,下面开始实施。

先整理一下代码,我们在 resources/views/partials 新建一个名为 nav.blade.php 的文件,把导航栏的代码提出来放到 nav.blade.php,然后把 master.blade.php 里曾经写导航栏的地方换成 include形式,如下:

那怎么能在一加载的时候就能获取到数据呢,这就需要回到之前讲过的 provider 这个利器。

我们通过命令行新建一个 provider 专门存放 view 层的业务代码:

此时,到 app/Providers 目录中打开 ViewComposerServiceProvider.php ,在 boot() 方法下添加几句话:

别忘记通过 use 形式引入 App\Article。

此时还没成功,你的 provider 还没有注册。打开 config.php ,找到 providers 数组,并在最下面添加一句App\Providers\ViewComposerServiceProvider::class,。保存文件并退出,刷新浏览器页面,访问article/create,成功说明ok了。哦对了,记得把 ArticlesController.php 的 index() 方法里的 latest 相关代码删掉。

总结

本节主要是学了一个 composer() 方法和 provider 的 boot() 方法。

boot() 方法区别与同一类中的 registry() 方法就是执行的顺序不同,只有当所有的接口都注册好了,才会进行 boot() 行为。

然后视图 view 的 composer() 方法的作用就是整合数据到视图,将 $latest 整合到 nav.blade.php 这个入口。入口整合好之后,之后的事情就方便多了,可以共享这些数据和行为。

发表评论

电子邮件地址不会被公开。 必填项已用*标注