Angular2:第二次避免DOM渲染

时间:2018-02-12 10:32:11

标签: angular

我有一个Tab控件,其中有两个标签。我在不同的标签中放置了两个Kendo Grid / Any组件。

当我第一次打开/选择选项卡时,它会在DOM中呈现相关的组件/ html。为了提高性能,我在标签上放置ngIf以仅显示活动标签html。所以现在Dom只显示活动标签html,但现在当我遍历其他标签并重新访问上一个标签时,它的组件/内容似乎再次渲染。我想第二次停止渲染。

注意:如果我将ngIf替换为hidden,那么它的工作方式已被接受,但由于许多手表和DOM与之相关,因此会降低性能。

实际上我的主要问题是,由于上述问题,当我导航到标签时,我的网格滚动位置每次都设置为顶部,而不应该保持相同的状态

以下是我所做的代码的某些部分。

标签内容html中的

条件(在DOM中仅渲染选定的标签)

<div class="tab-heading-outer">
    <div class="tab-heading">
        <ul id="ulOpenedTabs" class="nav nav-tabs main-tabs" role="tablist">
            <li>                 
                <span class="ellipsis"> {{tab.Header}} </span>
            </li>
        </ul>
    </div>
</div>

<div class="tab-content" *ngIf="tab.IsSelected">
    <ng-content>
    <!--Html goes here-->
    </ng-content>
</div>

5 个答案:

答案 0 :(得分:3)

如果你真的不想从DOM中删除组件并在打开选项卡时重新渲染它,那么另一种解决方案可能是:

  • 使用// starts a session session_start(); // compare db value with session if($_SESSION['score'] == $dbValue){ ... } 隐藏组件。
  • 当标签关闭时,使用ChangeDetectorRef.detach()从更改检测树中删除组件。
  • 当打开标签页以获取最新数据时,将更改检测添加回ChangeDetectorRef.reattach()组件。

根据组件的实施方式,这可以解决您的性能问题。特别是如果你非常依赖于Observables和异步管道(如你所愿),如果没有检查模板的变化,就不应该进行计算。

引用<ul id="someid"> <li class="someclass"></li> <li class="someclass"></li> <li class="someclass"></li> <li class="someclass"></li> </ul> 的文档:

  

想象一下,数据不断变化,每秒多次。出于性能原因,我们希望每五秒检查并更新一次列表。我们可以通过分离组件的变化检测器并每五秒进行一次本地检查来做到这一点。

你会做同样的事情,但不是基于时间的,而是基于标签是否打开。

您所要做的就是在组件构造函数中注入ChangeDetectorRef并将更改检测挂钩到[hidden]属性:

detach()

现在,您只需设置@Input()constructor(private changeDetector: ChangeDetectorRef) {} @Input() set visible(visible: boolean) { if(!visible) { changeDetector.detach(); } else { changeDetector.reattach(); } } 即可控制组件是否获得新数据。

您可以在ChangeDetectorRef的官方文档中找到另一个full example

答案 1 :(得分:2)

我不知道您对标签的实施情况,但为什么不使用一个变量来指示标签是否至少被选中一次以进行渲染?

<div class="tab-heading-outer">
    <div class="tab-heading">
        <ul id="ulOpenedTabs" class="nav nav-tabs main-tabs" role="tablist">
            <li>                 
                <span class="ellipsis" (click)="onTabSelected(tab)"> {{tab.Header}} </span>
            </li>
        </ul>
    </div>
</div>

<div class="tab-content" *ngIf="renderedTabs[tab.index]"  [hidden]="!tab.ISelected">
    <ng-content>
    <!--Html goes here-->
    </ng-content>
</div>

//component.ts

private renderedTabs : boolean[] = new Array(numberOfTabsHere);

onTabSelected(tab: Tab) 
{
    this.renderedTabs[tab.index] = true;
}

如果您可以修改tab的实现以直接在Tab对象上包含变量,则可以简化上面的代码

<div class="tab-heading-outer">
    <div class="tab-heading">
        <ul id="ulOpenedTabs" class="nav nav-tabs main-tabs" role="tablist">
            <li>                 
                <span class="ellipsis" (click)="tab.rendered=true"> {{tab.Header}} </span>
            </li>
        </ul>
    </div>
</div>

<div class="tab-content" *ngIf="tab.rendered" [hidden]="!tab.ISelected">
    <ng-content>
    <!--Html goes here-->
    </ng-content>
</div>

答案 2 :(得分:1)

您可以使用[hidden]="condition"代替*ngIf="condition"吗? *ngIffalse删除它所在的元素及其来自DOM的所有子元素时[hidden]。然而,当true[hidden]="false"时,html仍在DOM中,但在var reservationSchema = new Schema({ lcode: Number, reserved_days: [daySchema], }); var daySchema = new Schema({ pk: Number, date: String, price: Number, payment_type: String, payment_date: String, room: { room_id: String, name: String } }); 之前,屏幕上的不可见直到Reservation.find({ $or: [{ "reserved_days.room.room_id": { $in: req.body.reservation.reserved_days } }, { "reserved_days.date": { $in: req.body.reservation.reserved_days } }] }).exec(function(err, found) ; < / p>

答案 3 :(得分:1)

我创建了一个指令来实现此目标。它的名称是ngxCacheIf,它旨在实现您所需要的。 该指令首先充当"../static/js/index.js" ,然后充当ngIf。因此,仅渲染一次内容,然后将其隐藏显示。
在我的情况下,我用它代替了ngSwitch,以将先前渲染的内容保留在原位并保存性能。

您将以这种方式使用它:

[hidden]

这是一个实时示例:https://ngx-cache-if.stackblitz.io

这是npm,我昨天创建的,所以随时发表评论,还有github附带:

https://www.npmjs.com/package/ngx-cache-if

答案 4 :(得分:0)

注意:如果我用隐藏替换ngIf,那么它可以接受,但是由于许多手表和DOM与之相关,因此性能成本很高。

  

是的,这对您的问题来说是一个完美的解决方案。但是如果你遇到任何性能问题,那么你应该需要手动将前一部分的滚动部分设置为由temp变量采用(使用)的网格。

您可能也需要此解决方案:how to move div scroll position based on button click in angular 2

相关问题