Angular Abstracts & Data Mutations

问题描述

@H_502_0@我遇到了一个相当奇怪的错误?这与基于抽象类的组件有关(或者我的猜测是这样)。

@H_502_0@因此有多个兄弟组件根据带有 *ngFor 的数组长度进行渲染。兄弟姐妹(基于抽象类)通过 @Input 属性获取他们的数据,然后以他们的方式处理数据并显示它。到现在为止还挺好。 ChangeDetectionStrategy.OnPush ftw 等。但是,一旦我将鼠标悬停在其中一个组件上,数据就会立即发生变化(我没有其他解释或正确的术语)并且正在重置为该模板中的最后一个兄弟。

<Router-outlet>
  <ParentComponent>
    *ngFor
    <Sibling1>
      <ChildComponentA>
      <ChildComponentB>
    <Sibling2>
      <ChildComponentA>
      <ChildComponentB>
    <SiblingN>
      <ChildComponentA>
      <ChildComponentB>
@H_502_0@我已经断点了代码的每一行——一切都设置正确。但是一旦我将鼠标悬停在组件上,我相信更改检测就会启动并从最后一个兄弟姐妹那里获取数据并覆盖所有其他兄弟姐妹。不深,请注意!兄弟姐妹的孩子仍然是正确的,并按原样显示一切。但是该悬停的同级组件的模板已损坏。我真的迷路了。 我使用了 [...array]array.slice() 以及不确保数组唯一的方法。到目前为止没有任何帮助。

@H_502_0@这是一个示例(代码相当复杂,只能将其转储到此处)。

@H_502_0@parent.component.html

<ng-container *ngIf="v === 'user'">
    <div *ngFor="let e of employees">

        <div>
            <h3>{{ e | name }}</h3>
        </div>
        
        <ng-container *ngTemplateOutlet="days; context: { e: e }"></ng-container>

    </div>
</ng-container>

<ng-template #days let-l="l" let-e="e">
    <div>
        <sibling
            [weeks]="weeks"
            [viewmode]="v"
            [loc]="l"
            [emp]="e"
            [realDates]="realDates"></sibling>
    </div>
</ng-template>
@H_502_0@这是sibling.component.html

    <div *ngFor="let day of selectedWeek;">
        <div>
            <i *ngIf="viewmode == 'location'"
                class="ico"
                [ngClass]="{
                    'i-x-o': !day.isOpenOnDay && day.isspecialDay,'i-day-time': day.isOpenOnDay,'is-special': day.isspecialDay
                }"></i>
            <childA></childA>
        </div>

        <div>
            <childB [day]="day"></childB>
        </div>

    </div>
@H_502_0@<childB> 保持原样,显示 day 的数据没问题。但是,一旦我将鼠标悬停在 childAchildB 或什至带有图标类的 <i> 上,就会使用来自最后一个兄弟的 day 对象。兄弟组件中的 selectedWeek一个weeks 输入派生的数组,然后进行操作、切片和展开等等。

  • parentComponent:ChangeDetectionStrategy.Default
  • 兄弟:ChangeDetectionStrategy.OnPush
  • childA:ChangeDetectionStrategy.Default
  • childB:ChangeDetectionStrategy.OnPush

解决方法

对于任何想知道的人:解决方案是将变量 selectedWeek 转换为函数。在那之后,一切都按预期进行。所以在 sibling.component.html 中:

<div *ngFor="let day of selectedWeek()">
    <div>
        <i *ngIf="viewMode == 'location'"
            class="ico"
            [ngClass]="{
                'i-x-o': !day.isOpenOnDay && day.isSpecialDay,'i-day-time': day.isOpenOnDay,'is-special': day.isSpecialDay
            }"></i>
        <childA></childA>
    </div>

    <div>
        <childB [day]="day"></childB>
    </div>

</div>

然后在 sibling.component.ts

public function selectedWeek(): Array<any> {
  // do stuff,return an array
}

我仍然没有弄清楚变量不起作用的原因。