Angular2 +中具有嵌套组件不必要的主机包装器和ngTemplateOutlet的可访问列表

问题描述

我正在准备将创建可访问列表(没有ARIA标签)的一组组件。这意味着我需要一个Angular代码生成这样的html:

<dl>
    <dt></dt>
    <dd></dd>
</dl>

<dl>
    <div>
        <dt></dt>
        <dd></dd>
    </div>
</dl>

<ul>
    <li></li>
    <li></li>
</ul>

其中dl / ul最好是单独的成分<summary-list>,而dt / dd或li将属于另一个单独的成分<summary-item>

增加更多的复杂性,我想创建第三个组件<summary-column>,该组件允许在第二列中呈现列表的一部分。

目前,我的summary-list.component.html如下:

<dl class="row">
    <div class="columns small-10">
        <ng-container *ngFor="let item of listItems">
            <ng-container *ngTemplateOutlet="item.content"></ng-container>
        </ng-container>
    </div>

    <ng-content></ng-content>

    <ng-content select="[data-summary-column]"></ng-content>
</dl>

summary-list.component.ts

import {
    AfterViewInit,ChangeDetectorRef,Component,ContentChildren,NgModule,QueryList,} from '@angular/core';
import { CommonModule } from '@angular/common';
import {
    SummaryItemComponentModule,SummaryItemComponent,} from '@src/app/components/summary-list/components/summary-item/summary-item.component';

@Component({
    selector: 'app-summary-list',templateUrl: './summary-list.component.html',styleUrls: [],})
export class SummaryListComponent implements AfterViewInit {
    @ContentChildren(SummaryItemComponent) listItems: QueryList<
        SummaryItemComponent
    >;
    constructor(private changeDetectorRef: ChangeDetectorRef) {}

    ngAfterViewInit() {
        this.changeDetectorRef.detectChanges();
    }
}

@NgModule({
    declarations: [SummaryListComponent],imports: [CommonModule,SummaryItemComponentModule],exports: [SummaryListComponent],})
export class SummaryListComponentModule {}

summary-item.component.html

<ng-template>
    <dt class="fw-medium">
        <ng-content select="[data-label]"></ng-content>
    </dt>
    <dd class="mb-3">
        <ng-content select="[data-description]"></ng-content>
    </dd>
</ng-template>

summary-item.component.ts

import { Component,TemplateRef,ViewChild } from '@angular/core';
import { CommonModule } from '@angular/common';
import { SummaryColumnComponentModule } from '@src/app/components/summary-list/components/summary-column/summary-column.component';

@Component({
    selector: '[app-summary-item]',templateUrl: './summary-item.component.html',})
export class SummaryItemComponent {
    @ViewChild(TemplateRef)
    content: TemplateRef<any>;
}

@NgModule({
    declarations: [SummaryItemComponent],SummaryColumnComponentModule],exports: [SummaryItemComponent],})
export class SummaryItemComponentModule {}

summary-column.component.html

<ng-container>
    <ng-container *ngFor="let item of listInsideColumnItems">
        <ng-container *ngTemplateOutlet="item.content"></ng-container>
    </ng-container>

    <ng-content></ng-content>
</ng-container>

summary-column.component.js

import {
    AfterViewInit,forwardRef,} from '@angular/core';
import { CommonModule } from '@angular/common';
import { SummaryItemComponent } from '@components/summary-list/components/summary-item/summary-item.component';

@Component({
    selector: '[data-summary-column]',templateUrl: './summary-column.component.html',})
export class SummaryColumnComponent implements AfterViewInit {
    @ContentChildren(forwardRef(() => SummaryItemComponent),{
        descendants: true,})
    listInsideColumnItems: QueryList<SummaryItemComponent>;

    constructor(private changeDetectorRef: ChangeDetectorRef) {}

    ngAfterViewInit() {
        this.changeDetectorRef.detectChanges();
    }
}

@NgModule({
    declarations: [SummaryColumnComponent],imports: [CommonModule],exports: [SummaryColumnComponent],})
export class SummaryColumnComponentModule {}

用法是:

    <app-summary-list>
        <!--column 1-->

        <div app-summary-item>
            <span data-label>Hello</span>
            <span data-description>World</span>
        </div>

        <div app-summary-item>
            <span data-label>Hello2</span>
            <span data-description>World2</span>
        </div>

        <div app-summary-item>
            <span data-label>Hello3</span>
            <span data-description>World3</span>
        </div>

        <!--column 2-->

        <div data-summary-column class="columns small-10">
            <div app-summary-item>
                <span data-label>Hello4</span>
                <span data-description>World4</span>
            </div>

            <div app-summary-item>
                <span data-label>Hello5</span>
                <span data-description>World5</span>
            </div>

            <div app-summary-item>
                <span data-label>Hello6</span>
                <span data-description>World6</span>
            </div>
        </div>
    </app-summary-list>

最终,代码将产生以下html结构:

<app-summary-list>
    <dl class="row">
        <div class="columns small-10">
            <dt class="fw-medium ng-star-inserted">
                <span data-label="">Hello</span>
            </dt>
            <dd class="mb-3 ng-star-inserted">
                <span data-description="">World</span>
            </dd>
            <!--bindings={
  "ng-reflect-ng-template-outlet": "[object Object]"
}--><!--ng-container-->
            <dt class="fw-medium ng-star-inserted">
                <span data-label="">Hello2</span>
            </dt>
            <dd class="mb-3 ng-star-inserted">
                <span data-description="">World2</span>
            </dd>
            <!--bindings={
  "ng-reflect-ng-template-outlet": "[object Object]"
}--><!--ng-container-->
            <dt class="fw-medium ng-star-inserted">
                <span data-label="">Hello3</span>
            </dt>
            <dd class="mb-3 ng-star-inserted">
                <span data-description="">World3</span>
            </dd>
            <!--bindings={
  "ng-reflect-ng-template-outlet": "[object Object]"
}--><!--ng-container--><!--bindings={
  "ng-reflect-ng-for-of": "[object Object],[object Object"
}-->
        </div>
        <div app-summary-item=""><!--container--></div>
        <div app-summary-item=""><!--container--></div>
        <div app-summary-item=""><!--container--></div>
        <div data-summary-column="" class="columns small-10">
            <dt class="fw-medium ng-star-inserted">
                <span data-label="">Hello4</span>
            </dt>
            <dd class="mb-3 ng-star-inserted">
                <span data-description="">World4</span>
            </dd>
            <!--bindings={
  "ng-reflect-ng-template-outlet": "[object Object]"
}--><!--ng-container-->
            <dt class="fw-medium ng-star-inserted">
                <span data-label="">Hello5</span>
            </dt>
            <dd class="mb-3 ng-star-inserted">
                <span data-description="">World5</span>
            </dd>
            <!--bindings={
  "ng-reflect-ng-template-outlet": "[object Object]"
}--><!--ng-container-->
            <dt class="fw-medium ng-star-inserted">
                <span data-label="">Hello6</span>
            </dt>
            <dd class="mb-3 ng-star-inserted">
                <span data-description="">World6</span>
            </dd>
            <!--bindings={
  "ng-reflect-ng-template-outlet": "[object Object]"
}--><!--ng-container--><!--bindings={
  "ng-reflect-ng-for-of": "[object Object],[object Object"
}-->
            <div app-summary-item="" class="ng-star-inserted">
                <!--container-->
            </div>
            <div app-summary-item="" class="ng-star-inserted">
                <!--container-->
            </div>
            <div app-summary-item="" class="ng-star-inserted">
                <!--container-->
            </div>
            <!--ng-container-->
        </div>
    </dl>
</app-summary-list>

请解释一下是否有可能摆脱不必要的div <div app-summary-item="" class="ng-star-inserted">

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)