Angular2+ 自定義Tree組件(參考Angular-material的CdkTree)

爲了方便, 本文全部的Angular均表示Angula2及以上版本,對於使用Angular1/Angular.js的讀者可做爲參考html

前言

目前正在寫一個AngularMarkdown編輯器,須要一個樹形組件來寫文件系統。恰好以前用過Angular Material樹形組件,就想照着寫一個。畢竟直接把Angular Material引進來會多出其餘用不到的組件,並且本身實現還能更深刻學習Angularnode

介紹

在寫以前我百度了一通,發現大部分文章的Tree組件實現都是把節點模板直接寫在了組件裏,相似下面git

<!--Tree組件-->
<tree>
    <tree-node></tree-node>
</tree>
<!--TreeNode組件-->
<tree-node>
    <!--本節點內容-->
    {{ nodeName }}
    <!--子節點-->
    <tree-node *ngIf="hasChildren">
    </tree-node>
<tree-node>

說明一下: Tree組件裏面包含TreeNode組件,TreeNode組件內部實現了遞歸子節點的邏輯。
其實這樣的結構已經足夠知足個人需求了,可是(由於強迫症)這樣的可重用性幾乎是沒有,由於節點的內容已經寫死在TreeNode組件裏了。
而後我想到了Angular MaterialCdkTree。他的結構以下github

<tree dataSource="ds">
    <tree-node>
        <!--本節點內容-->
        {{ nodeName }}
        <!--子節點出口-->
        <outlet></outlet>
    </tree-node>
</tree>

說明: 簡單的說就是CdkTree<tree-node>裏的內容做爲一個模板保存起來,而後根據數據源遞歸渲染出來。這樣咱們就能夠在不修改TreeTreeNode組件前提下改變其內容。markdown

實現

在實現以前須要理解Angular的幾個裝飾器,學過Angular的應該都不會陌生。編輯器

  • @ViewChild - 在視圖中查詢匹配的第一個元素
  • @ViewChildren - 在視圖中查詢匹配的全部元素
  • @ContentChild - 在組件標籤包裹的內容中查詢匹配的第一個元素
  • @ContentChildren - 在組件標籤包裹的內容中查詢匹配的全部元素

View和Content的區別
View: 在組件的模板中定義的內容,即咱們手動寫在xxx.component.html裏的內容
Content: 在Host元素的<opening><closeing>標籤中的內容學習

概覽

在Tree組件中有四個比較重要的類spa

  • @Component: TreeComponent
  • @Component: TreeNodeComponent
  • @Directive: TreeNodeOutletDirective
  • @Directive: TreeNodeDefDirective

TreeComponent

該組件就是咱們要是實現的Tree組件,用於包裹TreeNodecode

TreeNodeComponent

樹節點組件,咱們自定義的模板就寫在這裏面component

TreeNodeOutletDirective

這個指令設置了子節點的出口位置

TreeNodeDefDirective

這個指令用來定義樹節點所需的數據,即咱們使用這個指令讓模板可使用每一個樹節點對應的數據

實現

咱們先看一下完成後的樣子

<nb-tree [dataSource]="fileTree">
    <nb-tree-node *nbTreeNodeDef="let data = data">
        <li>
          <span>{{ data.title }}</span>
        </li>
        <ul>
          <ng-container nbTreeNodeOutlet></ng-container>
        </ul>
    </nb-tree-node>
</nb-tree>

(標籤前面的nb請忽略,這只是默認的前綴)上面是完成後的簡易版。
咱們能夠看到在tree組件上設置了dataSource

而後在treeNodeDef指令中咱們導出了數據對象data。而後在模板中使用了它<span>{{ data.title }}</span>

最後咱們在<ng-container>上用treeNodeOutlet指令設置了子節點的出口。
懶得詳細寫實習了。。。有空再寫吧。本文主要提供一個通用樹形組件的思路。

想看代碼的,看結尾。有一個不是很完善的tree組件,我用在正在寫的Markdown編輯器上了。

結尾

Github: tree組件連接

相關文章
相關標籤/搜索