gpt4 book ai didi

php - CodeIgniter 创建 n 级深度导航

转载 作者:可可西里 更新时间:2023-11-01 13:28:07 25 4
gpt4 key购买 nike

我需要一些帮助。我创建了一个动态菜单导航栏,它根据我设置的顺序显示菜单项。我正在使用这个 nestedsortable插件,用于订购我的菜单项,但目前我的菜单只有 2 级,所以基本上是这样的:

Item1
Item2
> Subitem2.1
> Subitem2.2
Item3
etc etc.

我想做的是用 n 级制作它,所以基本上是这样的:

Item1
Item2
> Subitem2.1
>> Subitem2.1.1
> Subitem2.2
Item3
etc etc.

并且每个项目都可以达到 n 级深度。问题是,如果我为我的菜单项设置一个超过 2 级深度的新订单,我会收到错误消息,并且该订单不会存储在数据库中。我该如何解决这个问题???

数据库结构是这样的:

table: Menu
id (pk)
menu_item
parent_id // it is the id of the parent menu item
order

这是我的主要(模型)功能:

// save the order of the menu items
public function save_order($items){
if (count($items)>0) {
foreach ($items as $order => $item) {
if ($item['item_id'] != '') {

$data = array(
'parent_id' => (int)$item['parent_id'],
'order' => $order
);

$this->db->set($data)
->where($this->_primary_key, $item['item_id'])
->update($this->_table_name);
}
}
}
}

// fetch the menu items (parents & children) from the last order set
public function get_menu(){

$this->db->select('id, menu_item, parent_id');
$this->db->order_by('parent_id, order');
$menu_items = $this->db->get('menu')->result_array();

$arr = array();
foreach ($menu_items as $item) {

// the item has no parent
if (!$item['parent_id']) {
$arr[$item['id']] = $item; // e.g. $arr(4 => array())
} // the item is a child
else {
// e.g. $arr(4 => array('children' => array()))
$arr[$item['parent_id']]['children'][] = $item;
}
}
return $arr;
}

更新

如需额外帮助:我进行了测试,并在两种情况下将项目数组转储到屏幕上:

第一种情况:有 2 个级别(目前是这样):我按此顺序设置项目

  • 项目 1
  • 项目 2
    • 第 4 项
  • 第 3 项
  • 第 5 项

结果和预期的一样:

Array
(
[1] => Array
(
[id] => 1
[menu_item] => Item1
[parent_id] => 0
)

[2] => Array
(
[id] => 2
[menu_item] => Item2
[parent_id] => 0
[children] => Array
(
[0] => Array
(
[id] => 4
[menu_item] => Item4
[parent_id] => 2
)

)

)

[3] => Array
(
[id] => 3
[menu_item] => Item3
[parent_id] => 0
)

[5] => Array
(
[id] => 5
[menu_item] => Item5
[parent_id] => 0
)

)

第二种情况:有 n 级:我尝试按以下顺序设置菜单项:

  • 项目 1
  • 项目 2
    • 项目 5
      • 第 4 项
  • 第 3 项

结果是这样的:

Array
(
[1] => Array
(
[id] => 1
[menu_item] => Item1
[parent_id] => 0
)

[2] => Array
(
[id] => 2
[menu_item] => Item2
[parent_id] => 0
[children] => Array
(
[0] => Array
(
[id] => 5
[menu_item] => Item5
[parent_id] => 2
)

)

)

[3] => Array
(
[id] => 3
[menu_item] => Item3
[parent_id] => 0
)

[4] => Array
(
[children] => Array
(
[0] => Array
(
[id] => 4
[menu_item] => Item4
[parent_id] => 4
)

)

)

)

在这种情况下,我收到错误并且无法正常工作。我得到的错误是:

消息:未定义索引:page_id消息:未定义索引:menu_item

在我的 View 文件中:

function nav($menu_items, $child = false){
$output = '';

if (count($array)) {
$output .= ($child === false) ? '<ol class="sortable">' : '<ol>' ;

foreach ($menu_items as $item) {
$output .= '<li id="list_' . $item['id'] . '">'; // here is the line of the 1st error
$output .= '<div>' . $item['menu_item'] . '</div>'; // 2nd error

//check if there are any children
if (isset($item['children']) && count($item['children'])) {
$output .= nav($item['children'], true);
}
$output .= '</li>';
}
$output .= '</ol>';
}
return $output;
}


echo nav($menu_items);

最佳答案

考虑到数据库输出,项目似乎正确存储在数据库中。问题属于 get_menu() 方法及其创建输出的算法。

为了创建一个n 级 深菜单,您应该递归地遍历项目。

开始吧:

function prepareList(array $items, $pid = 0)
{
$output = array();

# loop through the items
foreach ($items as $item) {

# Whether the parent_id of the item matches the current $pid
if ((int) $item['parent_id'] == $pid) {

# Call the function recursively, use the item's id as the parent's id
# The function returns the list of children or an empty array()
if ($children = prepareList($items, $item['id'])) {

# Store all children of the current item
$item['children'] = $children;
}

# Fill the output
$output[] = $item;
}
}

return $output;
}

您可以将上述逻辑用作 helper 函数(在 CodeIgniter 中)或您的 Controller 类中的private 方法。

然后在 get_menu() 方法中调用该函数/方法,如下所示:

public function get_menu()
{
$this->db->select('id, menu_item, parent_id');
$this->db->order_by('parent_id, order');
$menu_items = $this->db->get('menu')->result_array();

return prepareList($menu_items);
}

注意:我使用 prepareList() 作为辅助(全局)函数。如果您决定将其用作私有(private)方法,则应在所有地方(甚至在函数本身内部)将函数名称替换为 $this->prepareList()

这是 Online Demo .

关于php - CodeIgniter 创建 n 级深度导航,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21599957/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com