私はいくつかのAngularライブラリを開発しているので、開発者向けにシンプルで簡単に再利用できるソリューションを作成するのが大好きです。最近、私のTwitterフォロワーの1人が、データを階層ツリー(ツリービュー)で表示するコンポーネントを作成する方法を尋ねてきました。
最小限のロジックでさまざまなユースケースをカバーできるので、この種の問題が大好きです。この記事では、そのような問題を解決するときの私の考え方について説明します。
免責事項:このチュートリアルは、Angular学習者の聴衆を対象としています。再帰型、再帰コンポーネントを作成し、その中のハンドラー関数によって渡されたデータを変換する方法を理解している場合は、スキップできます。
では、何が必要ですか?
, . ?
: , . , .
TypeScript:
export type MultidimensionalArray<string> =
| string
| ReadonlyArray<MultidimensionalArray<string>>;
TypeScript recursive type references :
readonly items: MultidimensionalArray<string> = [
"Hello",
["here", "is", ["some", "structured"], "Data"],
"Bye"
];
(«» («» («» …)))… !
, ? . , , , .
export type MultidimensionalArray<T> =
| T
| ReadonlyArray<MultidimensionalArray<T>>;
- !
Angular-
Angular . tree view, , .
tree view:
—
, isArray
, HostBinding, .
@Component({
selector: "m-dimensional-view",
templateUrl: "./m-dimensional-view.template.html",
styleUrls: ["./m-dimensional-view.styles.less"],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class MultidimensionalViewComponent<T> {
@Input()
value: MultidimensionalArray<T> = [];
@HostBinding("class._array")
get isArray(): boolean {
return Array.isArray(this.value);
}
}
isArray- *ngIf
, *ngFor
m-dimensional-view , — .
, , .
<ng-container *ngIf="isArray; else itemView">
<m-dimensional-view
*ngFor="let item of value"
[value]="item"
></m-dimensional-view>
</ng-container>
<ng-template #itemView>
{{ value }}
</ng-template>
, , .
:host {
display: block;
&._array {
margin-left: 20px;
}
}
margin-left , LESS
, :
toString ( {{value}}
).
, , toString-. , [object Object]
— -. , - . : « ?».
:
@Component({})
export class MultidimensionalViewComponent<T> {
// ...
@Input()
stringify: (item: T) => string = (item: T) => String(item);
// ...
}
, . String.
:
<ng-container *ngIf="isArray; else itemView">
<m-dimensional-view
*ngFor="let item of value"
[stringify]="stringify"
[value]="item"
></m-dimensional-view>
</ng-container>
<ng-template #itemView>
{{stringify(value)}}
</ng-template>
stringify , , .
. : , , , .
Waterplea CSS-, :
…
?
ng-polymorheus. , .
npm i @tinkoff/ng-polymorpheus
«», «», «», «». :
import { PolymorpheusContent } from "@tinkoff/ng-polymorpheus";
// ...
@Component({
selector: "m-dimensional-view",
templateUrl: "./m-dimensional-view.template.html",
styleUrls: ["./m-dimensional-view.styles.less"],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class MultidimensionalViewComponent<T> {
@Input()
value: MultidimensionalArray<T> = [];
@Input()
content: PolymorpheusContent = "";
@HostBinding("class._array")
get isArray(): boolean {
return Array.isArray(this.value);
}
}
stringify polymorpheus-outlet. . , . — , , context .
. :
readonly itemsWithIcons: MultidimensionalArray<Node> = [
{
title: "Documents",
icon: "https://www.flaticon.com/svg/static/icons/svg/210/210086.svg"
},
[
{
title: "hello.doc",
icon: "https://www.flaticon.com/svg/static/icons/svg/2306/2306060.svg"
},
{
title: "table.csv",
icon: "https://www.flaticon.com/svg/static/icons/svg/2306/2306046.svg"
}
]
];
polymorheus , :
<m-dimensional-view
[value]="itemsWithIcons"
[content]="itemView"
></m-dimensional-view>
<ng-template #itemView let-icon="icon" let-title="title">
<img alt="icon" width="16" [src]="icon" />
{{title}}
</ng-template>
, tree view . let-icon
, ng-template. :
ng-polymorheus: Stackblitz
, , HTML. , , , .
, , , .