Ich entwickle mehrere Angular-Bibliotheken, daher liebe ich es, einfache und leicht wiederverwendbare Lösungen für Entwickler zu entwickeln. Kürzlich fragte mich einer meiner Twitter- Follower , wie man eine Komponente erstellt, die ihre Daten in einer hierarchischen Baumstrukturansicht anzeigt.
Ich liebe diese Art von Problemen, weil sie die Möglichkeit bieten, viele verschiedene Anwendungsfälle mit einem Minimum an Logik abzudecken. In diesem Artikel werde ich beschreiben, wie ich denke, wenn ich solche Probleme löse.
Haftungsausschluss: Dieses Tutorial richtet sich an ein Publikum von Angular-Lernenden. Wenn Sie verstehen, wie Sie einen rekursiven Typ, eine rekursive Komponente, erstellen und die von der Handlerfunktion darin übergebenen Daten konvertieren, können Sie diese überspringen.
Was brauchen wir also?
, . ?
: , . , .
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. , , , .
, , , .