Angular 使用ng模板为儿童重复html

Angular 使用ng模板为儿童重复html,angular,ng-template,Angular,Ng Template,我认为这很简单,但由于某种原因我无法理解。 我正在构建一个简单的子菜单。我已经创建了组件: export class SubMenuComponent implements OnInit { @Input() links: MenuItem[]; constructor() {} ngOnInit(): void {} } 菜单项如下所示: export class MenuItem { label: string; path: string;

我认为这很简单,但由于某种原因我无法理解。 我正在构建一个简单的子菜单。我已经创建了组件:

export class SubMenuComponent implements OnInit {
    @Input() links: MenuItem[];

    constructor() {}

    ngOnInit(): void {}
}
菜单项如下所示:

export class MenuItem {
    label: string;
    path: string;
    open: boolean;
    children?: MenuItem[];
}
<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>
Html如下所示:

export class MenuItem {
    label: string;
    path: string;
    open: boolean;
    children?: MenuItem[];
}
<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>

    看起来我使用的模板不正确,因此我将其更改为:

    <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>
    
    <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>
    
    {{link.label} 键盘箭头向下 键盘箭头向上
    但我仍然得到了错误:(

    templateRef.createEmbeddedView不是函数


    我明白了,这是因为我的模板id与实际模型相同。因此我将其更改为:

    <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>
    
    <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>
    
      {{link.label} 键盘箭头向下 键盘箭头向上