轻松递归无限分类
protected $idName = 'stc_id';
protected $parentName = 'stc_parent_id';
/**
* 获取子集并递归
* @param $data
* @param $id
* @param array $new_arr
* @return array
*/
private function whileWhere($data,$id,&$new_arr=[])
{
$select_frist = $this->get_child_array($data,$id);
foreach ($select_frist as $Keies => $value) {
$new_obj = $this->get_child_array($data,$value[$this->idName]);
if(count($new_obj)){
$new_value = [];
$new_arr[] = array_merge($value,["node"=> $this->whileWhere($data,$value[$this->idName],$new_value[])]);
continue;
}
$new_arr[] = $value;
}
return $new_arr;
}
/**
* 子类集
* @param $data
* @param $id
* @return array
*/
protected function get_child_array($data,$id)
{
$new_data = [];
foreach ($data as $k=>$v){
if($v[$this->parentName] === $id){
$new_data[] = array_merge($data[$k],$this->is_child($data,$v[$this->idName]));
}
}
return $new_data;
}
/**
* 查询是否有子集
* @param $data
* @param $id
* @return array
*/
protected function is_child($data,$id)
{
foreach ($data as $k=>$v){
if($id === $v[$this->parentName] ){
return ['child'=>true];
}
}
return ['child'=>false];
}
请不要使用数据库查询操作递归,用语言本身才不会被外部约束!
以上使用id 父id 两个字段完成递归,举一反三哟!
结果:
array(3) { [0] => array(7) { ["stc_id"] => int(1) ["stc_name"] => string(6) "灏忓崕" ["stc_parent_id"] => int(0) ["stc_state"] => int(1) ["stc_sort"] => int(1) ["child"] => bool(true) ["node"] => array(1) { [0] => array(7) { ["stc_id"] => int(3) ["stc_name"] => string(6) "灏忓洓" ["stc_parent_id"] => int(1) ["stc_state"] => int(0) ["stc_sort"] => int(0) ["child"] => bool(true) ["node"] => array(1) { [0] => array(6) { ["stc_id"] => int(4) ["stc_name"] => string(6) "灏忎簲" ["stc_parent_id"] => int(3) ["stc_state"] => int(0) ["stc_sort"] => int(0) ["child"] => bool(false) } } } } } [1] => array(6) { ["stc_id"] => int(5) ["stc_name"] => string(6) "灏忓叚" ["stc_parent_id"] => int(0) ["stc_state"] => int(0) ["stc_sort"] => int(0) ["child"] => bool(false) } [2] => array(6) { ["stc_id"] => int(2) ["stc_name"] => string(6) "灏忕櫧" ["stc_parent_id"] => int(0) ["stc_state"] => int(0) ["stc_sort"] => int(0) ["child"] => bool(false) } }
分类菜单数据渲染案例:
php:
//#########无限循环公共方法 /** * @param $data * @param $id * @param array $new_arr * @return array */ function whileWhere($data,$id,$idName,$parentName,&$new_arr=[],$mode='mode:node') { $select_frist = get_child_array($data,$id,$idName,$parentName,$mode); foreach ($select_frist as $Keies => $value) { $new_obj = get_child_array($data,$value[$idName],$idName,$parentName,$mode); if(count($new_obj)){ $new_value = []; if($mode === 'mode:node'){ $new_arr[] = array_merge($value,["node"=>whileWhere($data,$value[$idName],$idName,$parentName,$new_value,$mode)]); }elseif($mode === 'mode:array_push'){ $nodes = whileWhere($data,$value[$idName],$idName,$parentName,$new_value,$mode); array_push($new_arr,$value); if(count($nodes)) foreach ($nodes as $key =>$vlaue){ array_push($new_arr,$vlaue); } } continue; } $new_arr[] = $value; }; return $new_arr; } /** * @param $data * @param $id * @return array */ function get_child_array($data,$id,$idName,$parentName,$mode) { $new_data = []; foreach ($data as $k=>$v){ if($v[$parentName] === $id){ $new_data[] = array_merge($data[$k],is_child($data,$v[$idName],$parentName)); } } return $new_data; } /** * @param $data * @param $id * @return array */ function is_child($data,$id,$parentName) { foreach ($data as $k=>$v){ if($id === $v[$parentName] ){ return ['child'=>true]; } } return ['child'=>false]; } //#控制器 public function index(MicroGoodsStyleCategory $category) { $data = $category->field('style_name,style_id,style_parent')->order('sort asc,style_id asc')->select()->toArray(); $arr_calss = []; $classed = whileWhere($data,0,'style_id','style_parent',$arr_calss,'mode:array_push'); return json(msg_array(1,'ok',$classed)); }
js:
var take_str = '#take'; $(take_str).treetable({ expandable: true});
css:
*{ text-align: left; margin: 0 auto; } .center,.center *{ text-align: center; } .width-30{ width: 30%;float: left; } .width-70{ width:70%;float: left;; } .width-50{ width:50%;float: left; } .width-100{ width:100%;float: left; } .padding_15,.padding_15 *{ padding: 0 15px; -moz-box-sizing: border-box; /*Firefox3.5+*/ -webkit-box-sizing: border-box; /*Safari3.2+*/ -o-box-sizing: border-box; /*Opera9.6*/ -ms-box-sizing: border-box; /*IE8*/ box-sizing: border-box; /*W3C标准(IE9+,Safari5.1+,Chrome10.0+,Opera10.6+都符合box-sizing的w3c标准语法)*/ } .floatL{ float: left; } .btn{ display: inline-block; font-weight: 400; text-align: center; white-space: nowrap; vertical-align: middle; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; border: 1px solid transparent; padding: .375rem .75rem; font-size: 1rem; line-height: 1.5; border-radius: .25rem; transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out; } .btn-primary { color: #fff; background-color: #007bff; border-color: #007bff; } .selected a{ color: #fff; } .style_management table tr { height: 30px; font-size: 1rem; line-height: 1.5; white-space: nowrap; vertical-align: middle; transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out; } ._rem{ display: inline-block; font-weight: 400; white-space: nowrap; vertical-align: middle; padding: .375rem .75rem; font-size: 1rem; line-height: 1.5; border-radius: .25rem; transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out; } .form_group{ padding: 10px; width: 100%; height: auto; clear: both; float: left; } .form_group *{ padding: 0 auto; } .form_group .form-control { display: block; padding: .375rem .75rem; font-size: 1rem; line-height: 1.5; color: #495057; background-color: #fff; background-clip: padding-box; border: 1px solid #ced4da; border-radius: .25rem; transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out; } .heightA,.heightA *{ height: auto; } .clear{ clear: both; } .error-b{ border: 1px solid #FF0000 !important; } .bgr60{ background-color: #320000 !important; }
template:
<thead> <tr> <td>自定义分类</td> </tr> </thead> <tbody> {{each datas}} {{set v = $value}} <tr data-tt-id="{{v.style_id}}" data-tt-parent-id="{{v.style_parent}}"> <td class="width-70 floatL ">{{v.style_name}}</td> <td class="width-30 floatL center"> <a href="#" class="width-50 edit" data-id="{{v.style_id}}"> 编辑</a> <a href="#" class="width-50 del" data-id="{{v.style_id}}">删除</a> </td> </tr> {{/each}} </tbody>
Html:
<link rel="stylesheet" href="//cdn.bootcss.com/jquery-treetable/3.2.0/css/jquery.treetable.css"> <link rel="stylesheet" href="//cdn.bootcss.com/jquery-treetable/3.2.0/css/jquery.treetable.theme.default.css"> <link rel="stylesheet" href="//cdn.bootcss.com/jquery-modal/0.9.1/jquery.modal.css"> <table id="take"> <script type="text/javascript" src="//cdn.bootcss.com/jquery-treetable/3.2.0/jquery.treetable.min.js"></script>
效果:(jquery-treetable 在数据显示上,其实没有特别的能帮到帮忙。它一定需要你去在返回数据时,按层级的排列数据,否则你会觉得很烦恼。数据参考格式:
[
{
"style_name": "欧美风",
"style_id": 6,
"style_parent": 0,
"child": true
},
{
"style_name": "美式",
"style_id": 10,
"style_parent": 6,
"child": true
},
{
"style_name": "田园风",
"style_id": 11,
"style_parent": 10,
"child": false
},
{
"style_name": "中式风",
"style_id": 8,
"style_parent": 0,
"child": false
},
{
"style_name": "美国风",
"style_id": 9,
"style_parent": 0,
"child": false
}
]