無限級分類之Laravel-nestedset擴充套件包的使用

Weiwen發表於2022-01-14

Laravel-nestedset是Laravel框架中的一個無限級分類的擴充套件包,它的實現有別於傳統的鄰接表模型,採用的是一種新的分層資料模型叫巢狀集合模型,這種模型能夠實現快速查詢,運用在少修改、頻查詢的業務場景中能夠提升較大的查詢效率。下面我就帶著大家一步一步來熟悉這個擴充套件。

u=3352133920,2187839175&fm=26&gp=0.jpg

1.進入到Laravel專案的根目錄中,用composer安裝kalnoy/nestedset。

composer require kalnoy/nestedset

1.建立好資料遷移檔案。

php artisan make:migration create_category_table

2.進入database/migrations目錄下,開啟生成的遷移檔案,並新增需要的欄位。

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
//引入NestedSet類
use Kalnoy\Nestedset\NestedSet;

class CreateCategoryTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('category', function (Blueprint $table) {
            //主鍵ID
            $table->id();
            //新增分類的名稱欄位
            $table->string('name')->default('');
            //在此新增此方法,nestedset將會自動生成:_lft、_rgt、parent_id三個欄位
            NestedSet::columns($table);
            //根據實際場景需要決定需不需要軟刪除
            $table->softDeletes();
            //新增建立時間、更新時間欄位
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('category');
    }
}

3.遷移檔案調整好之後,我們就可以執行遷移操作,建立出分類表,執行之後如下所示。

php artisan migrate

image.png

image.png

4.建立模型檔案

php artisan make:model CategoryModel

5.開啟該模型檔案,引入NodeTrait。

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
//引入NodeTrait
use Kalnoy\Nestedset\NodeTrait;

class CategoryModel extends Model
{
    //使用NodeTrait
    use HasFactory,NodeTrait;

    protected $table = 'category';

    protected $fillable = ['name'];

}

6.若想要替換欄位_lft、_rgt包括parent_id的名稱可以做如下操作

image.png

image.png

1.新增路由

//顯示節點
Route::get('node/show',[CategoryController::class,'showNodes']);
//建立節點
Route::get('node/create',[CategoryController::class,'createNode']);
//移動節點
Route::get('node/move',[CategoryController::class,'moveNode']);
//刪除節點
Route::get('node/delete',[CategoryController::class,'deleteNode']);

2.新增控制器

php artisan make:controller CategoryController
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\CategoryModel;

class CategoryController extends Controller
{
    //顯示節點
    public function showNodes()
    {

    }

    //建立節點
    public function createNode()
    {

    }

    //移動節點
    public function moveNode()
    {

    }

    //刪除節點
    public function deleteNode()
    {

    }
}

(1)建立節點並新增到樹節點的末端

1.通過模型的構造方法傳參的形式建立單節點

$model = new CategoryModel(['name' => '節點A']);
$model->save();

2.直接針對模型的屬性賦值來建立單節點

$model = new CategoryModel();
$model->name = '節點B';
$model->save();

3.呼叫模型的create方法建立單節點或者多節點(可包含子節點)

//建立一個單節點,預設建立的節點在根節點
CategoryModel::create(['name' => '節點C']);
//一次性建立多個節點
CategoryModel::create([
            'name' => '節點D',
            //使用children來定義子節點
            'children' => [
                [
                    'name' => '節點E',
                    'children' => [
                        ['name' => '節點F']
                    ]
                ],
                [
                    'name' => '節點G'
                ]
            ]
        ]);

4.建立之後資料庫資料以及樹節點顯示如下

image.png

[
    {
        "id": 1,
        "name": "節點A",
        "_lft": 1,
        "_rgt": 2,
        "parent_id": null,
        "deleted_at": null,
        "created_at": "2020-12-18T03:12:43.000000Z",
        "updated_at": "2020-12-18T03:12:43.000000Z",
        "children": []
    },
    {
        "id": 2,
        "name": "節點B",
        "_lft": 3,
        "_rgt": 4,
        "parent_id": null,
        "deleted_at": null,
        "created_at": "2020-12-18T03:13:11.000000Z",
        "updated_at": "2020-12-18T03:13:11.000000Z",
        "children": []
    },
    {
        "id": 3,
        "name": "節點C",
        "_lft": 5,
        "_rgt": 6,
        "parent_id": null,
        "deleted_at": null,
        "created_at": "2020-12-18T03:14:22.000000Z",
        "updated_at": "2020-12-18T03:14:22.000000Z",
        "children": []
    },
    {
        "id": 4,
        "name": "節點D",
        "_lft": 7,
        "_rgt": 14,
        "parent_id": null,
        "deleted_at": null,
        "created_at": "2020-12-18T03:14:46.000000Z",
        "updated_at": "2020-12-18T03:14:46.000000Z",
        "children": [
            {
                "id": 5,
                "name": "節點E",
                "_lft": 8,
                "_rgt": 11,
                "parent_id": 4,
                "deleted_at": null,
                "created_at": "2020-12-18T03:14:46.000000Z",
                "updated_at": "2020-12-18T03:14:46.000000Z",
                "children": [
                    {
                        "id": 6,
                        "name": "節點F",
                        "_lft": 9,
                        "_rgt": 10,
                        "parent_id": 5,
                        "deleted_at": null,
                        "created_at": "2020-12-18T03:14:46.000000Z",
                        "updated_at": "2020-12-18T03:14:46.000000Z",
                        "children": []
                    }
                ]
            },
            {
                "id": 7,
                "name": "節點G",
                "_lft": 12,
                "_rgt": 13,
                "parent_id": 4,
                "deleted_at": null,
                "created_at": "2020-12-18T03:14:46.000000Z",
                "updated_at": "2020-12-18T03:14:46.000000Z",
                "children": []
            }
        ]
    }
]

(2)為指定的父節點新增子節點,並且新增在子節點列表的尾部(若子節點已經存在,則會將該子節點移動到父節點的子節點列表中)

1.使用子節點的appendToNode方法

//首先建立一個子節點
$node = new CategoryModel(['name' => '節點H']);
//然後找一個父節點(假如以節點E作為父節點,id是5)
$parentNode = CategoryModel::find(5);
//將子節點新增到父節點中
$node->appendToNode($parentNode)->save();

2.使用父節點的appendNode方法

//首先建立一個子節點
$node = new CategoryModel(['name' => '節點I']);
//然後找一個父節點(假如以節點E作為父節點,id是5)
$parentNode = CategoryModel::find(5);
//使用父節點的appendNode方法新增子節點
$parentNode->appendNode($node);

3.使用父節點的children()關係

//首先找一個父節點(假如以節點E作為父節點,id是5)
$parentNode = CategoryModel::find(5);
//使用父節點的children()方法新增子節點
$parentNode->children()->create(['name' => '節點J']);

4.使用子節點的parent()關係的

//首先建立一個子節點
$node = new CategoryModel(['name' => '節點K']);
//然後找一個父節點(假如以節點E作為父節點,id是5)
$parentNode = CategoryModel::find(5);
//使用子節點的parent()關係
$node->parent()->associate($parentNode)->save();

5.使用子節點的parent_id屬性設定將子節點新增到指定的父節點

//首先建立一個子節點
$node = new CategoryModel(['name' => '節點L']);
//然後找一個父節點(假如以節點E作為父節點,id是5)
$parentNode = CategoryModel::find(5);
//設定子節點的parent_id為父節點
$node->parent_id = $parentNode->id;
//設定完成之後儲存
$node->save();

6.使用模型的靜態方法將子節點新增到父節點中

//首先找一個父節點(假如以節點E作為父節點,id是5)
$parentNode = CategoryModel::find(5);
//呼叫模型的create靜態方法
CategoryModel::create(['name' => '節點M'],$parentNode);

7.從1~6方法執行之後,最終的樹結構圖如下所示

//執行上面的程式碼之後,我們來檢視一下樹節點
//新增加的節點都依次被新增到了節點E的children列表的尾部
 {
        "id": 4,
        "name": "節點D",
        "_lft": 7,
        "_rgt": 28,
        "parent_id": null,
        "deleted_at": null,
        "created_at": "2020-12-18T03:14:46.000000Z",
        "updated_at": "2020-12-18T03:14:46.000000Z",
        "children": [
            {
                "id": 5,
                "name": "節點E",
                "_lft": 8,
                "_rgt": 25,
                "parent_id": 4,
                "deleted_at": null,
                "created_at": "2020-12-18T03:14:46.000000Z",
                "updated_at": "2020-12-18T03:14:46.000000Z",
                "children": [
                    {
                        "id": 6,
                        "name": "節點F",
                        "_lft": 9,
                        "_rgt": 10,
                        "parent_id": 5,
                        "deleted_at": null,
                        "created_at": "2020-12-18T03:14:46.000000Z",
                        "updated_at": "2020-12-18T03:14:46.000000Z",
                        "children": []
                    },
                    {
                        "id": 9,
                        "name": "節點H",
                        "_lft": 11,
                        "_rgt": 12,
                        "parent_id": 5,
                        "deleted_at": null,
                        "created_at": "2020-12-18T05:27:21.000000Z",
                        "updated_at": "2020-12-18T05:27:21.000000Z",
                        "children": []
                    },
                    {
                        "id": 11,
                        "name": "節點I",
                        "_lft": 15,
                        "_rgt": 16,
                        "parent_id": 5,
                        "deleted_at": null,
                        "created_at": "2020-12-18T05:40:55.000000Z",
                        "updated_at": "2020-12-18T05:40:55.000000Z",
                        "children": []
                    },
                    {
                        "id": 12,
                        "name": "節點J",
                        "_lft": 17,
                        "_rgt": 18,
                        "parent_id": 5,
                        "deleted_at": null,
                        "created_at": "2020-12-18T05:45:48.000000Z",
                        "updated_at": "2020-12-18T05:45:48.000000Z",
                        "children": []
                    },
                    {
                        "id": 13,
                        "name": "節點K",
                        "_lft": 19,
                        "_rgt": 20,
                        "parent_id": 5,
                        "deleted_at": null,
                        "created_at": "2020-12-18T05:53:22.000000Z",
                        "updated_at": "2020-12-18T05:53:22.000000Z",
                        "children": []
                    },
                    {
                        "id": 14,
                        "name": "節點L",
                        "_lft": 21,
                        "_rgt": 22,
                        "parent_id": 5,
                        "deleted_at": null,
                        "created_at": "2020-12-18T05:57:52.000000Z",
                        "updated_at": "2020-12-18T05:57:52.000000Z",
                        "children": []
                    },
                    {
                        "id": 15,
                        "name": "節點M",
                        "_lft": 23,
                        "_rgt": 24,
                        "parent_id": 5,
                        "deleted_at": null,
                        "created_at": "2020-12-18T06:02:43.000000Z",
                        "updated_at": "2020-12-18T06:02:43.000000Z",
                        "children": []
                    }
                ]
            },
            {
                "id": 7,
                "name": "節點G",
                "_lft": 26,
                "_rgt": 27,
                "parent_id": 4,
                "deleted_at": null,
                "created_at": "2020-12-18T03:14:46.000000Z",
                "updated_at": "2020-12-18T03:14:46.000000Z",
                "children": []
            }
        ]
    }

(3)為指定的父節點新增子節點,並且新增在子節點列表的頭部(若子節點已經存在,則會將該子節點移動到父節點的子節點列表中)

1.使用子節點的prependToNode方法

//首先建立一個子節點
$node = new CategoryModel(['name' => '節點N']);
//然後找一個父節點(假如以節點E作為父節點,id是5)
$parentNode = CategoryModel::find(5);
//通過子節點的prependToNode方法
$node->prependToNode($parentNode)->save();

2.使用父節點的prependNode方法

//首先建立一個子節點
$node = new CategoryModel(['name' => '節點O']);
//然後找一個父節點(假如以節點E作為父節點,id是5)
$parentNode = CategoryModel::find(5);
//通過父節點的prependNode方法
$parentNode->prependNode($node);

3.執行以上兩個操作之後的資料結構如下

{
        "id": 4,
        "name": "節點D",
        "_lft": 7,
        "_rgt": 10,
        "parent_id": null,
        "deleted_at": null,
        "created_at": "2020-12-18T03:14:46.000000Z",
        "updated_at": "2020-12-18T03:14:46.000000Z",
        "children": [
            {
                "id": 7,
                "name": "節點G",
                "_lft": 8,
                "_rgt": 9,
                "parent_id": 4,
                "deleted_at": null,
                "created_at": "2020-12-18T03:14:46.000000Z",
                "updated_at": "2020-12-18T03:14:46.000000Z",
                "children": []
            },
            {
                "id": 5,
                "name": "節點E",
                "_lft": 12,
                "_rgt": 33,
                "parent_id": 4,
                "deleted_at": null,
                "created_at": "2020-12-18T03:14:46.000000Z",
                "updated_at": "2020-12-18T06:51:59.000000Z",
                "children": [
                    {
                        "id": 18,
                        "name": "節點O",
                        "_lft": 13,
                        "_rgt": 14,
                        "parent_id": 5,
                        "deleted_at": null,
                        "created_at": "2020-12-18T07:01:04.000000Z",
                        "updated_at": "2020-12-18T07:01:04.000000Z",
                        "children": []
                    },
                    {
                        "id": 17,
                        "name": "節點N",
                        "_lft": 15,
                        "_rgt": 16,
                        "parent_id": 5,
                        "deleted_at": null,
                        "created_at": "2020-12-18T06:53:11.000000Z",
                        "updated_at": "2020-12-18T06:53:11.000000Z",
                        "children": []
                    },
                    {
                        "id": 6,
                        "name": "節點F",
                        "_lft": 17,
                        "_rgt": 18,
                        "parent_id": 5,
                        "deleted_at": null,
                        "created_at": "2020-12-18T03:14:46.000000Z",
                        "updated_at": "2020-12-18T03:14:46.000000Z",
                        "children": []
                    },
                    {
                        "id": 9,
                        "name": "節點H",
                        "_lft": 19,
                        "_rgt": 20,
                        "parent_id": 5,
                        "deleted_at": null,
                        "created_at": "2020-12-18T05:27:21.000000Z",
                        "updated_at": "2020-12-18T05:27:21.000000Z",
                        "children": []
                    },
                    {
                        "id": 11,
                        "name": "節點I",
                        "_lft": 23,
                        "_rgt": 24,
                        "parent_id": 5,
                        "deleted_at": null,
                        "created_at": "2020-12-18T05:40:55.000000Z",
                        "updated_at": "2020-12-18T05:40:55.000000Z",
                        "children": []
                    },
                    {
                        "id": 12,
                        "name": "節點J",
                        "_lft": 25,
                        "_rgt": 26,
                        "parent_id": 5,
                        "deleted_at": null,
                        "created_at": "2020-12-18T05:45:48.000000Z",
                        "updated_at": "2020-12-18T05:45:48.000000Z",
                        "children": []
                    },
                    {
                        "id": 13,
                        "name": "節點K",
                        "_lft": 27,
                        "_rgt": 28,
                        "parent_id": 5,
                        "deleted_at": null,
                        "created_at": "2020-12-18T05:53:22.000000Z",
                        "updated_at": "2020-12-18T05:53:22.000000Z",
                        "children": []
                    },
                    {
                        "id": 14,
                        "name": "節點L",
                        "_lft": 29,
                        "_rgt": 30,
                        "parent_id": 5,
                        "deleted_at": null,
                        "created_at": "2020-12-18T05:57:52.000000Z",
                        "updated_at": "2020-12-18T05:57:52.000000Z",
                        "children": []
                    },
                    {
                        "id": 15,
                        "name": "節點M",
                        "_lft": 31,
                        "_rgt": 32,
                        "parent_id": 5,
                        "deleted_at": null,
                        "created_at": "2020-12-18T06:02:43.000000Z",
                        "updated_at": "2020-12-18T06:02:43.000000Z",
                        "children": []
                    }
                ]
            }
        ]
    }

(4)新增節點並插入到指定節點的前面或後面

1.新增節點插入到指定節點的前面

/*************************顯性 save****************************/
# 首先建立一個子節點
$node = new CategoryModel(['name' => '節點Q']);
# 然後找一個指定的節點(假如指定節點B,id是2)
$neighbor = CategoryModel::find(2);
# 將該節點插入到節點B的前面
$node->beforeNode($neighbor)->save();
/*************************顯性 save****************************/

//或者

/*************************隱性 save****************************/
# 首先建立一個子節點
$node = new CategoryModel(['name' => '節點Q']);
# 然後找一個指定的節點(假如指定節點B,id是2)
$neighbor = CategoryModel::find(2);
# 將該節點插入到節點B的前面
$node->insertBeforeNode($neighbor);
/*************************隱性 save****************************/
// 執行之後樹結構如下
[
    {
        "id": 1,
        "name": "節點A",
        "_lft": 1,
        "_rgt": 2,
        "parent_id": null,
        "deleted_at": null,
        "created_at": "2020-12-18T03:12:43.000000Z",
        "updated_at": "2020-12-18T03:12:43.000000Z",
        "children": []
    },
    {
        "id": 20,
        "name": "節點Q",
        "_lft": 3,
        "_rgt": 4,
        "parent_id": null,
        "deleted_at": null,
        "created_at": "2020-12-18T09:41:48.000000Z",
        "updated_at": "2020-12-18T09:41:48.000000Z",
        "children": []
    },
    {
        "id": 2,
        "name": "節點B",
        "_lft": 5,
        "_rgt": 6,
        "parent_id": null,
        "deleted_at": null,
        "created_at": "2020-12-18T03:13:11.000000Z",
        "updated_at": "2020-12-18T03:13:11.000000Z",
        "children": []
    },
    ...
]

2.新增節點插入到指定節點的後面

/*************************顯性 save****************************/
# 首先建立一個子節點
$node = new CategoryModel(['name' => '節點S']);
# 然後找一個指定的節點(假如指定節點B,id是2)
$neighbor = CategoryModel::find(2);
# 將該節點插入到節點B的後面
$node->afterNode($neighbor)->save();
/*************************顯性 save****************************/

//或者

/*************************隱性 save****************************/
# 首先建立一個子節點
$node = new CategoryModel(['name' => '節點S']);
# 然後找一個指定的節點(假如指定節點B,id是2)
$neighbor = CategoryModel::find(2);
# 將該節點插入到節點B的後面
$node->insertAfterNode($neighbor);
/*************************隱性 save****************************/
//執行之後樹結構如下
[
    {
        "id": 1,
        "name": "節點A",
        "_lft": 1,
        "_rgt": 2,
        "parent_id": null,
        "deleted_at": null,
        "created_at": "2020-12-18T03:12:43.000000Z",
        "updated_at": "2020-12-18T03:12:43.000000Z",
        "children": []
    },
    {
        "id": 20,
        "name": "節點Q",
        "_lft": 3,
        "_rgt": 4,
        "parent_id": null,
        "deleted_at": null,
        "created_at": "2020-12-18T09:41:48.000000Z",
        "updated_at": "2020-12-18T09:41:48.000000Z",
        "children": []
    },
    {
        "id": 2,
        "name": "節點B",
        "_lft": 7,
        "_rgt": 8,
        "parent_id": null,
        "deleted_at": null,
        "created_at": "2020-12-18T03:13:11.000000Z",
        "updated_at": "2020-12-18T03:13:11.000000Z",
        "children": []
    },
    {
        "id": 22,
        "name": "節點S",
        "_lft": 9,
        "_rgt": 10,
        "parent_id": null,
        "deleted_at": null,
        "created_at": "2020-12-18T09:57:56.000000Z",
        "updated_at": "2020-12-18T09:57:56.000000Z",
        "children": []
    },
    {
        "id": 3,
        "name": "節點C",
        "_lft": 11,
        "_rgt": 12,
        "parent_id": null,
        "deleted_at": null,
        "created_at": "2020-12-18T03:14:22.000000Z",
        "updated_at": "2020-12-18T07:29:22.000000Z",
        "children": []
    },
   ...
]

1.將集合資料樹形展現

//樹形結構展現(預設情況下,節點未進行排序展示,也就是說未根據depth欄位進行排序)
$tree = CategoryModel::get()->toTree();
//採用預設排序再轉換成樹形(預設排序是根據depth欄位從小到大的順序)
$tree = CategoryModel::defaultOrder()->get()->toTree();
//採用倒序排序再轉換成樹形(倒序排序是根據depth欄位從大到小的順序)
$tree = CategoryModel::reversed()->get()->toTree();

2.獲取節點資料的同時附帶每個節點的深度

//展現節點的時候,使用withDepth()方法,輸出的資料會帶一個深度欄位depth
$result = CategoryModel::withDepth()->get();
//按照深度值來篩選出節點
$result = CategoryModel::withDepth()->having('depth', '=', 1)->get();

image.png

3.獲取兄弟節點

//獲取某個節點的兄弟節點
$result = $node->getSiblings();
$result = $node->siblings()->get();
// 獲取相鄰的下一個兄弟節點
$result = $node->getNextSibling();
// 獲取後面的所有兄弟節點
$result = $node->getNextSiblings();
// 使用查詢獲得所有兄弟節點
$result = $node->nextSiblings()->get();
// 獲取相鄰的前一個兄弟節點
$result = $node->getPrevSibling();
// 獲取前面的所有兄弟節點
$result = $node->getPrevSiblings();
// 使用查詢獲得所有兄弟節點
$result = $node->prevSiblings()->get();

4.獲取祖先和後代節點

// 獲取該節點的所有祖先節點
$node->ancestors;
// 獲取該節點的所有後代節點
$node->descendants;
//獲取$id這個節點的所有祖先節點
$result = CategoryModel::ancestorsOf($id);
//獲取$id這個節點的所有祖先節點包括本節點
$result = CategoryModel::ancestorsAndSelf($id);
//獲取$id這個節點的所有子節點
$result = CategoryModel::descendantsOf($id);
//獲取$id這個節點的所有子節點包括本節點
$result = CategoryModel::descendantsAndSelf($id);

5.查詢資料的條件約束

//僅獲取根節點
$result = CategoryModel::whereIsRoot();
//獲取特定$id的節點後面的所有節點(不僅是兄弟節點)。
$result = CategoryModel::whereIsAfter($id);
//獲取特定$id的節點前面的所有節點(不僅是兄弟節點)。
$result = CategoryModel::whereIsBefore($id);
//查詢祖先的條件約束
$result = CategoryModel::whereAncestorOf($node)->get();
$result = CategoryModel::whereAncestorOrSelf($id)->get();
//查詢後代的條件約束
$result = CategoryModel::whereDescendantOf($node)->get();
$result = CategoryModel::whereNotDescendantOf($node)->get();
$result = CategoryModel::orWhereDescendantOf($node)->get();
$result = CategoryModel::orWhereNotDescendantOf($node)->get();
$result = CategoryModel::whereDescendantAndSelf($id)->get();
//結果集合中包含目標node自身
$result = Category::whereDescendantOrSelf($node)->get();

1.向上移動節點

//獲取需要移動的節點
$node = CategoryModel::find(1);
//將該節點向上移動1個位置
$node->up();
//將該節點向上移動3個位置(如果節點向上移動的位置超過了範圍,則移動無效)
$node->up(3);

2.向下移動節點

//獲取需要移動的節點
$node = CategoryModel::find(1);
//將該節點向下移動1個位置
$node->down();
//將該節點向下移動3個位置(如果節點向下移動的位置超過了範圍,則移動無效)
$node->down(3);

3.將一個已存在的節點設定為根節點

//將節點E設定為根節點
$node = CategoryModel::find(5);
// 隱性 save
$node->saveAsRoot();
// 或者
// 顯性 save
$node->makeRoot()->save();

4.將一個已經存在的節點移動到指定節點的前面或後面(該方法與前述插入的方法一致,區別在於如果節點不存在則會新建立節點再移動,而如果節點已經存在則直接移動)

$node = CategoryModel::find(5);
$neighbor = CategoryModel::find(3);
//顯性save
//將ID是5的節點移動到ID是3的節點的後面
$node->afterNode($neighbor)->save();
//將ID是5的節點移動到ID是3的節點的前面
$node->beforeNode($neighbor)->save();

//或者

// 隱性 save
//將ID是5的節點移動到ID是3的節點的後面
$node->insertAfterNode($neighbor);
//將ID是5的節點移動到ID是3的節點的前面
$node->insertBeforeNode($neighbor);

5.將一個節點移動到某個節點的子節點列表中(可以是列表的頭部,也可以是列表的尾部),該部分參考「三」-(2)以及「三」-(3)。

1.使用模型的delete方法刪除,節點的所有後代元素將一併刪除

//刪除
$node = CategoryModel::find(19);
$node->delete();

2.不可以使用以下的語句刪除,否則會破會樹結構

//不可以這樣刪除,請謹慎操作,否則破壞樹結構
? CategoryModel::where('id', '=', $id)->delete();

3.模型也支援軟刪除,在模型裡面新增SoftDeletes trait

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Kalnoy\Nestedset\NodeTrait;

class CategoryModel extends Model
{
    use HasFactory,NodeTrait,SoftDeletes;

    protected $table = 'category';

    protected $fillable = ['name'];

}

4.軟刪除之後我們可以檢視錶資料

image.png

1.檢查節點是否為其他節點的子節點

$bool = $node->isDescendantOf($parent);

2.檢查是否為根節點

$bool = $node->isRoot();

3.檢查樹節點是否被破環

$bool = CategoryModel::isBroken();

4.檢查當前節點是否是另外一個節點的子節點

$bool = $node−>isChildOf($otherNode);

5.檢查當前節點是否是另外一個節點的

$bool = $node−>isAncestorOf($otherNode);

6.檢查當前節點是否是另外一個節點的兄弟節點

$bool = $node−>isSiblingOf($otherNode);

7.檢查當前節點是否是葉子節點

$bool = $node->isLeaf();
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章