文章分类列表
上一篇介绍了添加文章分类,这篇介绍下列表的实现,分类列表不同于其它的列表,因为它是有层级的,我们这里限定为最多三级,而不是无限的。
首先,我们在/app/Models/Category模型里添加一个获取列表的方法。
public static function lists()
{
return Category::select(['id', 'type', 'parent_id', 'name', 'dir_name', 'pic', 'is_nav', 'sort', 'is_del'])->get();
}
这样是可以获取到分类的列表,但是有个问题,因为我们分类是有层级的,那这样的写法就是有问题的,怎么样才能按层级的方式读出数据呢?laravel给我们提供了模型关联,功能非常丰富。对于我们这个情况,可是使用一对多模型关联,因为一个父级,可能拥有多个子级,每个子级也会拥有自己的子级,所以是一对多关系。
我们在Category模型中,再增加一个方法
public function child()
{
return $this->hasMany(Category::class,'parent_id','id')
->select(['id', 'type', 'parent_id', 'name', 'dir_name', 'pic', 'is_nav', 'sort', 'is_del']);
}
child()方法中,有一个hasMany()方法,这个就代表了一对多的关系,第一个参数是要关联的类,指的是“多”的那一方,不是“一”的那一方,比如有一张用户表,一张订单表,一个用户可以有多个订单,这两张表是一对多的关系,“一”的那一方就是用户表,“多”的那一方就是订单表,hasMany()方法应该写到用户模型里,hasMany()的第一个参数就是订单模型,第二个参数就是外键,比如你订单表中会有一个用户id吧,这个用户id就是外键,通过用户id这个外键把用户和订单关联起来了,第三个参数就是本表的id,和第二个参数即外键对应,必须对应上,对应不上,是查不出数据的,两个参数搞反了也查不出数据,
在category表中,外键就是parent_id,它关联的是自己,因此hasMany()方法的第一个参数是Category类,第二个参数是parent_id,第三个参数是id,外键和主键关联起来。
我们管理起来了,那如何使用呢?很简单
public static function lists()
{
return Category::with('child')
->select(['id', 'type', 'parent_id', 'name', 'dir_name', 'pic', 'is_nav', 'sort', 'is_del'])
->where('parent_id', 0)
->where('is_del', 0)
->get();
}
和上边相比,多个一个with(),使用它就关联起来了,我们让控制器调用Category模型的lists()方法,打印一下结果,看看是什么情况。在CategoryController控制器中,加入一个lists()方法
public function lists(Request $request)
{
dd(Category::lists());
return view('admin.category');
}
dd()函数,是laravel提供的一个非常好用的打印方法。我们先看看打印出来的结果。
是一个对象,里边的信息非常的详细,但是看起来不方便,我们可以转成数组的形式展示
public function lists(Request $request)
{
dd(Category::lists()->toArray());
return view('admin.category');
}
我们把对象toArray()一下就好了,再看看结果
太好了,清晰多了。在我们查询出的结果中,多了一个“child”字段,而且“child”是个数组,说明这里会有多条信息,但是我们数据表中的数据都是父级数据,没有子级数据,我们到数据库中添加一条子级数据。在“新闻”这一级下,加一个“行业新闻”
因为行业新闻是新闻的子级或者下级,所以,parent_id是1。我们再刷新下页面看看
“child”字段中有数据了,说明“新闻”这个父级有了子级“行业新闻”,我们再添加一个“公司新闻”
再刷新页面看看
出来了吧!那现在只是二级,我们最多做到三级,那第三级怎么搞出来呢?非常简单,打开Category模型改下代码
public static function lists()
{
return Category::with('child.child')
->select(['id', 'type', 'parent_id', 'name', 'dir_name', 'pic', 'is_nav', 'sort', 'is_del'])
->where('parent_id', 0)
->where('is_del', 0)
->get();
}
与之前代码相比,with()的参数有变化,之前是with('child'),现在是with('child.child'),可以这么理解:
Category::with('child'),是取到父级的子级,Category::with('child.child')是取到父级的子级的子级,以此类推。
我们给行业新闻加一个子级“技术新闻”
行业新闻的id是4,技术新闻是行业新闻的子级,所以,技术新闻的paren_id是4,我们刷下新页面看看
技术新闻出现了,这个框架是不是很用啊,我的大爱呀!!我们修改下控制器,把数据传给视图展示出来
public function lists(Request $request)
{
$data['list'] = Category::lists();
return view('admin.category', $data);
}
控制搞定,我们去视图改点东西
@foreach($list as $val)
// 父级HTML
@foreach($val['child'] as $child)
// 二级HTML
@foreach($child['child'] as $cd)
// 三级HTML
@enforeach
@enforeach
@endforeach
通过@foreach,可以把分类列表给遍历出来。效果如下