Angular6 Form 仅在定期 zone.js 变化检测后响应

Angular6 Form only responds after periodic zone.js change detection

我有一个很奇怪的情况:在设置一个包含表单的组件后,与表单的交互非常慢。 单击下拉列表后,表单仅在 zone.js 超时发生并且周期性更改检测开始时才会做出反应。 知道为什么会这样吗?为什么 component/form 会在 zone.js 变化检测之外?我没有任何错误。

我唯一的调试输入是,在 chrome devtools 中进行性能分析时,我得到了点击事件,然后在 5-12 秒后,zone.js 触发了 UI 动画显示下拉选项。

在 Chrome DevTools Performance Profiler 中,如下所示:

我在分析后大约 2 秒点击下拉菜单:

然后 10 秒后,zone.js 执行触发下拉列表的定期更新:

两者之间,什么也没有发生。

我正在使用 NgRx,切换到具有表单的组件发生在 @Effect 中,我在其中调用路由器。

效果是这样的: (它也不适用于 RxJS5,所以它不应该与迁移有任何关系)

  @Effect()
  placesDetails$ = this.actions$
    .ofType<PlaceSelectedAction>(PLACE_SELECTED_ACTION)
    .pipe(
      switchMap((action: PlaceSelectedAction) =>
        this.placesService.loadPlacesDetails(action.payload)
      ),
      map(data => new PlaceDetailsLoadedAction(data)),
      tap(_ => this.router.navigate(["/place-details"]))
    );

组件本身是这样的:

import { Component } from "@angular/core";
import { Store } from "@ngrx/store";
import { ApplicationState } from "../store/application-state";
import { Router } from "@angular/router";
import { Card } from "../../../../shared/model/card";

@Component({
  selector: "app-place-details",
  templateUrl: "./place-details.component.html",
  styleUrls: ["./place-details.component.scss"]
})
export class PlaceDetailsComponent {
  card: Card;

  constructor(private store: Store<ApplicationState>, private router: Router) {
    this.store.subscribe(state => (this.card = state.cardDataState.card));
  }

  travelTypeLocation = [
    { value: "city", viewValue: "City" },
    { value: "beach", viewValue: "Beach" },
    { value: "mountains", viewValue: "Mountains" },
    { value: "countryside", viewValue: "Countryside" }
  ];

  travelTypeActivity = [
    { value: "relax", viewValue: "Relax" },
    { value: "sports", viewValue: "Sports" },
    { value: "culture", viewValue: "Culture" },
    { value: "party", viewValue: "Party" }
  ];

  travelTypeCompanions = [
    { value: "family", viewValue: "Family" },
    { value: "partner", viewValue: "Partner" },
    { value: "single", viewValue: "Single" },
    { value: "friends", viewValue: "Friends" },
    { value: "colleagues", viewValue: "Colleagues" }
  ];

  checkPlaceDetails() {
    //this.store.dispatch(new PlaceDetailsSubmitAction());
  }

  goBack() {
    this.router.navigate(["/search-places"]);
  }
}

这是HTML:

<div class="container" fxLayout.xs="column">
  <h3>Fill out Place Details</h3>

  <form>

    <mat-form-field class="full-width">
      <input
        matInput
        placeholder="Title"
        type="text"
        required
        name="title"
        [(ngModel)]="card.title">
      <mat-error *ngIf="card.title">{{ card.title }}</mat-error>
    </mat-form-field>

    <mat-form-field class="full-width">
      <input
        matInput
        placeholder="Description"
        type="text"
        name="description"
        required
        [(ngModel)]="card.description"
        />
    </mat-form-field>

    <mat-form-field class="full-width">
      <mat-select
        placeholder="Travel Type Location"
        name="travelTypeLocation"
        required
        [(ngModel)]="card.travelTypeLocation"
      >
        <mat-option *ngFor="let type of travelTypeLocation" [value]="type.value">
          {{ type.viewValue }}
        </mat-option>
      </mat-select>
    </mat-form-field>

    <mat-form-field class="full-width">
      <input
        matInput
        placeholder="Travel Dimension Location (e.g. surfing, biking, museum, theater)"
        type="text"
        name="travelDimensionLocation"
        required
        [(ngModel)]="card.travelDimensionLocation"
      />
    </mat-form-field>

    <mat-form-field class="full-width">
      <mat-select
        placeholder="Travel Type Activity"
        name="travelTypeActivity"
        required
        [(ngModel)]="card.travelTypeActivity"
      >
        <mat-option *ngFor="let type of travelTypeActivity" [value]="type.value">
          {{ type.viewValue }}
        </mat-option>
      </mat-select>
    </mat-form-field>

    <mat-form-field class="full-width">
      <input
        matInput
        placeholder="Travel Dimension Activity (e.g. modern city, historic city, hills, high mountains)"
        type="text"
        name="travelDimensionActivity"
        required
        [(ngModel)]="card.travelDimensionActivity"
      />
    </mat-form-field>

    <mat-form-field class="full-width">
      <mat-select
        placeholder="Travel Companions"
        name="travelTypeCompanions"
        required
        [(ngModel)]="card.travelTypeCompanions"
      >
        <mat-option *ngFor="let type of travelTypeCompanions" [value]="type.value">
          {{ type.viewValue }}
        </mat-option>
      </mat-select>
    </mat-form-field>

    <mat-form-field class="full-width">
      <input
        matInput
        placeholder="Duration"
        type="text"
        required
        name="duration"
        [(ngModel)]="card.averageDuration"
      />
    </mat-form-field>

    <mat-form-field class="full-width">
      <input
        matInput
        required
        placeholder="Cost (€)"
        type="number"
        name="cost"
        [(ngModel)]="card.cost"
      />
    </mat-form-field>

    <button mat-raised-button color="primary" (click)="checkPlaceDetails()">Add Card</button>
    <button mat-raised-button color="secondary" (click)="goBack()">Go Back</button>

  </form>
</div>

请告诉我什么是重要的?我迷路了。

谢谢!

这个很难弄清楚。但显然 zone.js 和 RxJS 存在错误。 在 polyfills 中包含 import 'zone.js/dist/zone-patch-rxjs'; 后,它现在按预期工作,在表单交互后没有延迟。