Angular 为使用 ng-template 的儿童重复 html
Angular repeat html for children using ng-template
我认为这很简单,但出于某种原因我无法理解。
我正在构建一个简单的子菜单。我已经创建了组件:
export class SubMenuComponent implements OnInit {
@Input() links: MenuItem[];
constructor() {}
ngOnInit(): void {}
}
MenuItem 看起来像这样:
export class MenuItem {
label: string;
path: string;
open: boolean;
children?: MenuItem[];
}
Html 看起来像这样:
<ul class="app-sub-menu list-unstyled">
<li *ngFor="let link of links" routerLinkActive="active"><a class="btn-link" [routerLink]="link.path"
routerLinkActive="active" [routerLinkActiveOptions]="{exact: link.path === '/'}">{{ link.label }}</a>
<span class="toggle" *ngIf="link.children?.length" (click)="link.open = !link.open">
<mat-icon *ngIf="link.isActive || link.open">keyboard_arrow_down</mat-icon>
<mat-icon *ngIf="!link.isActive && !link.open">keyboard_arrow_up</mat-icon>
</span>
<ul class="list-unstyled" [class.open]="link.open" *ngIf="link.children?.length">
<li *ngFor="let link of link.children" routerLinkActive="active"><a class="btn-link"
routerLinkActive="active" [routerLink]="link.path" #link>{{ link.label }}</a>
<span class="toggle" *ngIf="link.children?.length" (click)="link.open = !link.open">
<mat-icon *ngIf="link.isActive || link.open">keyboard_arrow_down</mat-icon>
<mat-icon *ngIf="!link.isActive && !link.open">keyboard_arrow_up</mat-icon>
</span>
<ul class="list-unstyled" [class.open]="link.open" *ngIf="link.children?.length">
<li *ngFor="let link of link.children" routerLinkActive="active"><a class="btn-link"
routerLinkActive="active" [routerLink]="link.path">{{ link.label }}</a>
</li>
</ul>
</li>
</ul>
</li>
</ul>
如您所见,当前的 子菜单 仅向下 3 级。我希望它可以无限嵌套。
所以我决定使用 ng-template,但我无法让它工作。
我认为这会很简单:
<ul class="app-sub-menu list-unstyled">
<ng-template *ngTemplateOutlet="link" *ngFor="let link of links"></ng-template>
</ul>
<ng-template #link>
<li *ngFor="let link of links" routerLinkActive="active"><a class="btn-link" [routerLink]="link.path"
routerLinkActive="active" [routerLinkActiveOptions]="{exact: link.path === '/'}">{{ link.label }}</a>
<span class="toggle" *ngIf="link.children?.length" (click)="link.open = !link.open">
<mat-icon *ngIf="link.isActive || link.open">keyboard_arrow_down</mat-icon>
<mat-icon *ngIf="!link.isActive && !link.open">keyboard_arrow_up</mat-icon>
</span>
<ul class="list-unstyled" [class.open]="link.open" *ngIf="link.children?.length">
<ng-template *ngTemplateOutlet="link" *ngFor="let link of link.children"></ng-template>
</ul>
</li>
</ng-template>
但是当我尝试使用它时,出现错误:
Can't have multiple template bindings on one element. Use only one attribute prefixed with *
所以我改成这样:
现在我收到一个新错误:
templateRef.createEmbeddedView is not a function
有谁知道我该怎么做才能让它发挥作用?
正在阅读:
看来我的模板使用不正确,所以我将其更改为:
<ul class="app-sub-menu list-unstyled">
<ng-container *ngTemplateOutlet="link; context: { $implicit: links }"></ng-container>
</ul>
<ng-template #link let-links>
<li *ngFor="let link of links" routerLinkActive="active"><a class="btn-link" [routerLink]="link.path"
routerLinkActive="active" [routerLinkActiveOptions]="{exact: link.path === '/'}">{{ link.label }}</a>
<span class="toggle" *ngIf="link.children?.length" (click)="link.open = !link.open">
<mat-icon *ngIf="link.isActive || link.open">keyboard_arrow_down</mat-icon>
<mat-icon *ngIf="!link.isActive && !link.open">keyboard_arrow_up</mat-icon>
</span>
<ul class="list-unstyled" [class.open]="link.open" *ngIf="link.children?.length">
<ng-container *ngTemplateOutlet="link; context: { $implicit: link.children }"></ng-container>
</ul>
</li>
</ng-template>
但我仍然收到错误:(
templateRef.createEmbeddedView is not a function
我想通了,那是因为我的模板id和实际模型一样。所以我把它改成这样:
<ul class="app-sub-menu list-unstyled">
<ng-template #nestedList let-links>
<li *ngFor="let link of links" routerLinkActive="active"><a class="btn-link" [routerLink]="link.path"
routerLinkActive="active" [routerLinkActiveOptions]="{exact: link.path === '/'}">{{ link.label }}</a>
<span class="toggle" *ngIf="link.children?.length" (click)="link.open = !link.open">
<mat-icon *ngIf="link.isActive || link.open">keyboard_arrow_down</mat-icon>
<mat-icon *ngIf="!link.isActive && !link.open">keyboard_arrow_up</mat-icon>
</span>
<ul class="list-unstyled" [class.open]="link.open" *ngIf="link.children?.length">
<ng-container *ngTemplateOutlet="nestedList; context: { $implicit: link.children }"></ng-container>
</ul>
</li>
</ng-template>
<ng-container *ngTemplateOutlet="nestedList; context: { $implicit: links }"></ng-container>
</ul>
我认为这很简单,但出于某种原因我无法理解。 我正在构建一个简单的子菜单。我已经创建了组件:
export class SubMenuComponent implements OnInit {
@Input() links: MenuItem[];
constructor() {}
ngOnInit(): void {}
}
MenuItem 看起来像这样:
export class MenuItem {
label: string;
path: string;
open: boolean;
children?: MenuItem[];
}
Html 看起来像这样:
<ul class="app-sub-menu list-unstyled">
<li *ngFor="let link of links" routerLinkActive="active"><a class="btn-link" [routerLink]="link.path"
routerLinkActive="active" [routerLinkActiveOptions]="{exact: link.path === '/'}">{{ link.label }}</a>
<span class="toggle" *ngIf="link.children?.length" (click)="link.open = !link.open">
<mat-icon *ngIf="link.isActive || link.open">keyboard_arrow_down</mat-icon>
<mat-icon *ngIf="!link.isActive && !link.open">keyboard_arrow_up</mat-icon>
</span>
<ul class="list-unstyled" [class.open]="link.open" *ngIf="link.children?.length">
<li *ngFor="let link of link.children" routerLinkActive="active"><a class="btn-link"
routerLinkActive="active" [routerLink]="link.path" #link>{{ link.label }}</a>
<span class="toggle" *ngIf="link.children?.length" (click)="link.open = !link.open">
<mat-icon *ngIf="link.isActive || link.open">keyboard_arrow_down</mat-icon>
<mat-icon *ngIf="!link.isActive && !link.open">keyboard_arrow_up</mat-icon>
</span>
<ul class="list-unstyled" [class.open]="link.open" *ngIf="link.children?.length">
<li *ngFor="let link of link.children" routerLinkActive="active"><a class="btn-link"
routerLinkActive="active" [routerLink]="link.path">{{ link.label }}</a>
</li>
</ul>
</li>
</ul>
</li>
</ul>
如您所见,当前的 子菜单 仅向下 3 级。我希望它可以无限嵌套。 所以我决定使用 ng-template,但我无法让它工作。 我认为这会很简单:
<ul class="app-sub-menu list-unstyled">
<ng-template *ngTemplateOutlet="link" *ngFor="let link of links"></ng-template>
</ul>
<ng-template #link>
<li *ngFor="let link of links" routerLinkActive="active"><a class="btn-link" [routerLink]="link.path"
routerLinkActive="active" [routerLinkActiveOptions]="{exact: link.path === '/'}">{{ link.label }}</a>
<span class="toggle" *ngIf="link.children?.length" (click)="link.open = !link.open">
<mat-icon *ngIf="link.isActive || link.open">keyboard_arrow_down</mat-icon>
<mat-icon *ngIf="!link.isActive && !link.open">keyboard_arrow_up</mat-icon>
</span>
<ul class="list-unstyled" [class.open]="link.open" *ngIf="link.children?.length">
<ng-template *ngTemplateOutlet="link" *ngFor="let link of link.children"></ng-template>
</ul>
</li>
</ng-template>
但是当我尝试使用它时,出现错误:
Can't have multiple template bindings on one element. Use only one attribute prefixed with *
所以我改成这样:
现在我收到一个新错误:
templateRef.createEmbeddedView is not a function
有谁知道我该怎么做才能让它发挥作用?
正在阅读:
看来我的模板使用不正确,所以我将其更改为:
<ul class="app-sub-menu list-unstyled">
<ng-container *ngTemplateOutlet="link; context: { $implicit: links }"></ng-container>
</ul>
<ng-template #link let-links>
<li *ngFor="let link of links" routerLinkActive="active"><a class="btn-link" [routerLink]="link.path"
routerLinkActive="active" [routerLinkActiveOptions]="{exact: link.path === '/'}">{{ link.label }}</a>
<span class="toggle" *ngIf="link.children?.length" (click)="link.open = !link.open">
<mat-icon *ngIf="link.isActive || link.open">keyboard_arrow_down</mat-icon>
<mat-icon *ngIf="!link.isActive && !link.open">keyboard_arrow_up</mat-icon>
</span>
<ul class="list-unstyled" [class.open]="link.open" *ngIf="link.children?.length">
<ng-container *ngTemplateOutlet="link; context: { $implicit: link.children }"></ng-container>
</ul>
</li>
</ng-template>
但我仍然收到错误:(
templateRef.createEmbeddedView is not a function
我想通了,那是因为我的模板id和实际模型一样。所以我把它改成这样:
<ul class="app-sub-menu list-unstyled">
<ng-template #nestedList let-links>
<li *ngFor="let link of links" routerLinkActive="active"><a class="btn-link" [routerLink]="link.path"
routerLinkActive="active" [routerLinkActiveOptions]="{exact: link.path === '/'}">{{ link.label }}</a>
<span class="toggle" *ngIf="link.children?.length" (click)="link.open = !link.open">
<mat-icon *ngIf="link.isActive || link.open">keyboard_arrow_down</mat-icon>
<mat-icon *ngIf="!link.isActive && !link.open">keyboard_arrow_up</mat-icon>
</span>
<ul class="list-unstyled" [class.open]="link.open" *ngIf="link.children?.length">
<ng-container *ngTemplateOutlet="nestedList; context: { $implicit: link.children }"></ng-container>
</ul>
</li>
</ng-template>
<ng-container *ngTemplateOutlet="nestedList; context: { $implicit: links }"></ng-container>
</ul>