理想情况下,我需要重新加载/重新渲染组件的模板,但是如果有更好的方法可以做到这一点,我将很乐意实现它。

所需的行为:

因此,我有一个用于菜单元素的组件。当(在另一个组件中)我单击一个IBO(可以说是某种“客户端”)时,我需要在菜单中添加一个新选项(我使用*ngIf),该选项将是“IBO Details”和一个子列表。

IBOsNavigationElement组件(菜单组件):

@Component({
    selector: '[ibos-navigation-element]',
    template: `
        <a href="#"><i class="fa fa-lg fa-fw fa-group"></i> <span
                class="menu-item-parent">{{'IBOs' | i18n}}</span>
        </a>
        <ul>
            <li routerLinkActive="active">
                <a routerLink="/ibos/IBOsMain">{{'IBOs Main' | i18n}} {{id}}</a>
            </li>
            <li *ngIf="navigationList?.length > 0">
                <a href="#">{{'IBO Details' | i18n}}</a>
                <ul>
                    <li routerLinkActive="active" *ngFor="let navigatedIBO of navigationList">
                        <a href="#/ibos/IboDetails/{{navigatedIBO['id']}}">{{navigatedIBO['name']}}</a>
                    </li>
                </ul>
            </li>
        </ul>
    `
})
export class IBOsNavigationElement implements OnInit {
    private navigationList = <any>[];


    constructor(private navigationService: NavigationElementsService) {
        this.navigationService.updateIBOsNavigation$.subscribe((navigationData) => {
                this.navigationList.push(navigationData);
                log.d('I received this Navigation Data:', JSON.stringify(this.navigationList));
            }
        );
    }

    ngOnInit() {
    }
}

最初,navigationList将为空[],因为用户没有单击任何IBO(客户端),但是一旦单击IBO,将填充列表,因此,我需要新选项显示在菜单中。

使用此代码,当我单击一个IBO时,创建了<li>元素及其子元素,但是:我只看到<li>元素。

问题:

菜单选项已生成,但布局样式未对其进行处理。需要使用所有元素对其进行初始化,以便知道如何显示菜单选项。

我需要重新加载该组件的模板才能正确显示菜单。

注意:

如果我使用不带*ngIf的模板,效果很好,但是从一开始我就将没有任何意义的IBO Details选项,因为初始化时未单击任何IBO。

template: `
        <a href="#"><i class="fa fa-lg fa-fw fa-group"></i> <span
                class="menu-item-parent">{{'IBOs' | i18n}}</span>
        </a>
        <ul>
            <li routerLinkActive="active">
                <a routerLink="/ibos/IBOsMain">{{'IBOs Main' | i18n}} {{id}}</a>
            </li>
            <li>
                <a href="#">{{'IBO Details' | i18n}}</a>
                <ul>
                    <li routerLinkActive="active" *ngFor="let navigatedIBO of navigationList">
                        <a href="#/ibos/IboDetails/{{navigatedIBO['id']}}">{{navigatedIBO['name']}}</a>
                    </li>
                </ul>
            </li>
        </ul>
    `

所需的输出:

在单击任何东西之前(在init上):

Angular2 : rendering/reloading a component&#39;s template-LMLPHP

单击IBO(客户端)后:

Angular2 : rendering/reloading a component&#39;s template-LMLPHP

更新1:

为了阐明我的意思:



如果,我的菜单组件被初始化而没有*ngIf:

<li>
    <a href="#">{{'IBO Details' | i18n}}</a>
        <ul>
            <li routerLinkActive="active" *ngFor="let navigatedIBO of navigationList">
                <a href="#/ibos/IboDetails/{{navigatedIBO['id']}}">{{navigatedIBO['name']}}</a>
            </li>
        </ul>
</li>

然后,布局样式可以根据以下结构生成菜单输出(参见图片):

<li>
   <a>
   <ul>
      <li *ngFor>
         <a>
      </li>
   </ul>
</li>

因此,添加+符号和子菜单行为等。

但是,如果初始化时不包含所有元素(当*ngIffalse<li>且未渲染其子级,因此布局不考虑它们来绘制/创建菜单),并且在渲染之后将这些元素添加到中,然后它们将存在于源代码中,但由于以下原因,我们将无法在菜单中看到它们:
  • 未创建+
  • 无子菜单行为
  • 最佳答案

    Angular有两种变更检测策略:

  • 默认策略,该策略自动检测模型中的更改并相应地重新呈现组件。
  • OnPush,仅在您明确要求组件执行操作时才重新渲染该组件
    所以。
    另请参阅https://angular.io/docs/ts/latest/api/core/index/ChangeDetectionStrategy-enum.html

  • 当页面上有多个元素或想要对呈现过程有更多控制时,OnPush策略可以具有更好的性能。

    为了使用此策略,您必须在组件中对其进行声明:
    @Component({
        selector: '[ibos-navigation-element]',
        template: `...`,
        changeDetection: ChangeDetectionStrategy.OnPush
    })
    

    并注入(inject)您的构造函数:
    constructor(
        private changeDetector: ChangeDetectorRef,
    ) {}
    

    当您要触发更改检测以便可以重新渲染组件时
    (在您的情况下,将新的IBO/客户端添加到模型后),请调用:
    this.changeDetector.markForCheck();
    

    查看官方教程中的现场演示:http://plnkr.co/edit/GC512b?p=preview

    如果问题不是关于更改检测,而是与CSS/SCSS样式有关,
    请记住,在Angular 2中,每个组件都有自己的CSS类集,
    它们不是由“ child ”元素“继承”的。他们是完全孤立的
    彼此之间。一种解决方案是创建全局CSS/SCSS样式。

    关于Angular2 : rendering/reloading a component's template,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43395808/

    10-11 13:19