Angular6 Form仅在定期zone.js更改检测后响应

时间:2018-07-22 20:48:02

标签: javascript angular forms zonejs

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

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

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

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

然后10秒钟后,zone.js进行了定期更新,该更新触发了下拉菜单: zone.js change detection runs and dropdown is triggered

在这之间什么也没发生。

我正在使用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>

请让我知道什么可能重要?我迷路了。

谢谢!

1 个答案:

答案 0 :(得分:0)

这个很难弄清楚。但是显然zone.js和RxJS出现了错误。 在import 'zone.js/dist/zone-patch-rxjs';中加入polyfills之后,它现在可以按预期工作,并且在表单交互后没有延迟。