Angular 2 : rendering/reloading a component's template

标签 angular typescript angular2-template

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

期望的行为:

所以,我有一个菜单元素组件。当(在另一个组件中)我点击一个 IBO (某种“客户”,比如说) 被点击时,我需要添加(我我正在使用 *ngIf ) 菜单中的一个新选项,即 IBO 详细信息 和一个子列表。

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 详细信息 选项,因为在初始化时没有点击 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>
    `

期望的输出:

在点击任何东西之前(在初始化时):

enter image description here

在我点击一个 IBO (客户) 之后:

enter image description here

更新 1:

澄清我的意思:

The menu option is generated but not proccessed by the layout styles

如果,我的菜单组件初始化时没有 *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 策略可以有更好的性能。

为了使用这个策略,你必须在你的组件中声明它:

@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 样式。

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

相关文章:

angular - 通过类选择器渲染 Angular2 组件

javascript - Angular 4 多级 Accordion 问题

javascript - 如何让 Angular 应用程序女巫通用 SSR 使用来自 json 文件的动态配置?

angular - 为每个HTTP请求创建进度条加载效果

angular - 如何防止 MatHorizo​​ntalStepper 中点击事件的默认行为

javascript - Mongoose : Best way to get values for an object before save

node.js - NestJS:如何注册 transient 和每个 Web 请求提供程序

typescript - 在初始声明 typescript 后声明变量类型

angular - 如何在 Angular 2 的 ngFor 中设置绑定(bind)?

html - Angular 2 中的模板驱动表单