理想情况下,我需要重新加载/重新渲染组件的模板,但是如果有更好的方法可以做到这一点,我将很乐意实现它。
所需的行为:
因此,我有一个用于菜单元素的组件。当(在另一个组件中)我单击一个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上):
单击IBO(客户端)后:
更新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>
因此,添加
+
符号和子菜单行为等。但是,如果初始化时不包含所有元素(当
*ngIf
为false
时<li>
且未渲染其子级,因此布局不考虑它们来绘制/创建菜单),并且在渲染之后将这些元素添加到中,然后它们将存在于源代码中,但由于以下原因,我们将无法在菜单中看到它们:+
最佳答案
Angular有两种变更检测策略:
所以。
另请参阅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/