LaravelVietnam / laravel-solutions

A Q&A board for helping members
27 stars 4 forks source link

[Package] Cách sử dụng thư viện Baum (Menu đa cấp) #16

Open tonamson opened 8 years ago

tonamson commented 8 years ago

Link package: https://github.com/etrepat/baum Blog chia sẽ kinh nghiệm của mình trong cuộc đời lập trình: https://tns93.wordpress.com/

Cập nhật hướng dẫn sử dụng (Level Sinh viên làm biến)

- Phần 1: Giới thiệu về package Baum

Đây là một gói giúp ta hỗ trợ nhanh việc làm menu đa cấp có thể áp dụng cho việc như làm category hoặc các việc khác. Mình thì dùng nó làm cho cate và cả hiện thông tin phân quyền này nọ ra :+1:

- Cách hoạt động của Baum theo hình ảnh capture

Để đọc đầy đủ thêm thì lên link trên giúp nhé :3

- Khởi tạo Model

namespace App;

use Baum\Node;

class Category extends Node
{
    protected $table = 'categories';

    // 'parent_id' column name
    protected $parentColumn = 'parent_id';

    // 'lft' column name
    protected $leftColumn = 'lft';

    // 'rgt' column name
    protected $rightColumn = 'rgt';

    // 'depth' column name
    protected $depthColumn = 'depth';

    // guard attributes from mass-assignment
    protected $guarded = array('id', 'parent_id', 'lft', 'rgt', 'depth');
}

Để tạo một thư mục cha sử dụng Baum

Cách của mình là tạo một Seeder để quản lý các Query khi mình dùng lệnh php artisan migrate --seed

Code để tạo một root node:

$root = Category::create(['name' => 'Root category']);

Để tạo một Child node của $root

$child1 = Category::create(['name' => 'Child 1']);
$child1->makeChildOf($root);

Hoặc cũng có thể dùng

$child1 = $root->children()->create(['name' => 'Child 1']);

Xóa một Node

$child1->delete();

Lấy cấp độ của Node

$root->getLevel() // return 0 (bởi vì nó là thư mục cha không phụ thuộc vào ai nên nó sẽ trả về 0)

Để chuyển một Node con từ Node này sang Node khác

$home = WebFunction::create(['name' => 'Trang chủ']);
$func = WebFunction::create(['name' => 'Chức năng']);
$managerAccount = WebFunction::create(['name' => 'Quản lý tài khoản', 'name_route' => 'mngAccount', 'name_permission' => 'mngAccount'])->makeChildOf($func);
WebFunction::create(['name' => 'Danh sách tài khoản', 'name_route' => 'mngListAccount', 'name_permission' => 'mngListAccount'])->makeChildOf($managerAccount);
WebFunction::create(['name' => 'Thêm tài khoản', 'name_route' => 'mngListAccount', 'name_permission' => 'mngListAccount'])->makeChildOf($managerAccount);

Ở đây mình tạo 2 Node root gồm (Trang chủ và Chức năng) Hình ảnh 1: capture

Mình dùng lệnh php artisan migrate:refresh --seed. Thì khúc Thêm tài khoản này nó đang là con của Quản lý tài khoản Nhưng khi mình thêm dòng php sau vào phía cuối code Seeder của mình

$home = WebFunction::create(['name' => 'Trang chủ']);
$func = WebFunction::create(['name' => 'Chức năng']);
$managerAccount = WebFunction::create(['name' => 'Quản lý tài khoản', 'name_route' => 'mngAccount', 'name_permission' => 'mngAccount'])->makeChildOf($func);
WebFunction::create(['name' => 'Danh sách tài khoản', 'name_route' => 'mngListAccount', 'name_permission' => 'mngListAccount'])->makeChildOf($managerAccount);
WebFunction::create(['name' => 'Thêm tài khoản', 'name_route' => 'mngListAccount', 'name_permission' => 'mngListAccount'])->makeChildOf($managerAccount);

//Code chuyển Node con sang làm con của một Node khác
WebFunction::where('name','like','Thêm tài khoản')->first()->makeChildOf($home);

Dữ liệu sẽ trở thành như hình sau:

capture

Các bạn để ý chổ mình khoanh tròn Từ hình 1: Column: parent_id \ có giá trị là 3 Từ hình 2: Column: parent_id có giá trị là 1**

Nghĩa là bây giờ id 5 này nó đã là con của id 1

Và tutorial cuối cùng: Biến thằng Node con trở thành Root Node Demo Code

WebFunction::where('name','like','Thêm tài khoản')->first()->makeRoot();

Cách truy xuất dữ liệu trình bày ra template thì em có đoạn code sau File Provider của em (Còn ai muốn hỏi gì về Provider thì đọc document Laravel nhé :3 còn hỏi tại sao em dùng nó thì em muốn là khi chạy được migrate rồi thì provider chạy câu truy xuất lấy dữ liệu để đổ menu ra template bằng viewshare luôn)

$nestedList = WebFunction::all()->toHierarchy()->toArray();
view()->share('menu_left', $nestedList);

Tạm thời em đổ dữ liệu ra dạng mảng được thông tin như sau:

capture Em sẽ dùng mảng này để đổ dữ liệu ra template còn ai có cao kiến khác thì xin góp ý kiến thêm nhé

Kết thúc việc tìm hiểu sơ thì em làm tạm bợ trình bày nó ra template như sau

Database:

capture

capture

capture

capture

Cập nhật ngày 18/06/2016: Cách hiển thị thông tin dạng thư mục cha của thư mục con

foreach($node->getAncestorsAndSelf() as $descendant) {
     echo "{$descendant->name}<br>";
}

Ảnh kết quả trả về capture

Kết thúc nếu còn thắc mắc gì các bạn cứ gửi câu hỏi lên đây :) Những câu hỏi ngu ngốc của bạn là kiến thức mới cho mình :) nó giúp mình có thể tư duy hơn trong việc lập trình. Cho nên các bạn đừng bao giờ tự nghĩ những câu hỏi của mình là những câu hỏi ngu ngốc :)

p/s: thành viên có thể ít check Github nên có thể share link lên group https://www.facebook.com/groups/laraconvn/ để alert mọi người cùng trả lời

chungth commented 8 years ago

@tonamson cái này e giải quyết được rồi nhỉ ?

tonamson commented 8 years ago

@chungth em giải quyết được theo cách của em rồi anh hôm nay em bận tí nên có thể viết tutorial hơi chậm

chungth commented 8 years ago

@tonamson em có blog riêng ko ? viết lên blog riêng rồi share link 💃

tonamson commented 8 years ago

Xong giải quyết trình bày từ A>Z nhé :3

trihtm commented 8 years ago

Link xem thêm về cấu trúc dữ liệu phân cấp, lý thuyết của nó :D

http://butchiso.com/2013/06/cau-truc-du-lieu-phan-cap-va-ung-dung.html

hungnm144 commented 6 years ago

có ai bị lỗi khi sử dụng Descendants() để lấy tất cả con của 1 node cha không nhỉ?