爲了方便, 本文全部的Angular
均表示Angula2及以上版本,對於使用Angular1
/Angular.js
的讀者可做爲參考html
目前正在寫一個Angular
的Markdown
編輯器,須要一個樹形組件來寫文件系統。恰好以前用過Angular Material
的樹形組件,就想照着寫一個。畢竟直接把Angular Material
引進來會多出其餘用不到的組件,並且本身實現還能更深刻學習Angular
。node
在寫以前我百度了一通,發現大部分文章的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 Material
的CdkTree
。他的結構以下github
<tree dataSource="ds"> <tree-node> <!--本節點內容--> {{ nodeName }} <!--子節點出口--> <outlet></outlet> </tree-node> </tree>
說明: 簡單的說就是CdkTree
把<tree-node>
裏的內容做爲一個模板保存起來,而後根據數據源遞歸渲染出來。這樣咱們就能夠在不修改Tree
和TreeNode
組件前提下改變其內容。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
該組件就是咱們要是實現的Tree
組件,用於包裹TreeNode
code
樹節點組件,咱們自定義的模板就寫在這裏面component
這個指令設置了子節點的出口位置
這個指令用來定義樹節點所需的數據,即咱們使用這個指令讓模板可使用每一個樹節點對應的數據
咱們先看一下完成後的樣子
<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
組件連接