代码之家  ›  专栏  ›  技术社区  ›  r3plica

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

  •  0
  • r3plica  · 技术社区  · 4 年前

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

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

    这个 菜单项 看起来像这样:

    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模板 ,但我不能让它工作。 我以为这很简单:

    <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>
    

    但当我尝试使用它时,我遇到了一个错误:

    一个元素上不能有多个模板绑定。仅使用一个前缀为的属性*

    所以我把它改成了这样:

    现在我得到一个新的错误:

    templateRef.createEmbeddedView不是函数

    有人知道我能做些什么来让这个工作吗?


    阅读此文:

    https://medium.com/@nehaabrol87/the-power-of-angulars-ngtemplateoutlet-used-to-implement-a-nested-data-structure-11c741e6b48c

    看起来我使用的模板不正确,所以我把它改成了这样:

    <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不是函数

    0 回复  |  直到 4 年前
        1
  •  2
  •   r3plica    4 年前

    我想出来了,这是因为我的模板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>