如何仅在值更改时调用管道

Ali*_*aig 5 primeng angular-pipe angular

我将 angular 2 与primeng p-dropdown 一起使用,并且有一个案例,当用户选择父项时,我需要过滤子项下拉列表。我是用自定义管道做的

<p-dropdown [options]="carTypesOptions" [(ngModel)]="CarTypeId" name="CarTypeId"></p-dropdown>
<p-dropdown [options]="carMakeOptions | filterCarMakes: CarTypeId" [(ngModel)]="CarMakeId" name="CarMakeId"></p-dropdown>
Run Code Online (Sandbox Code Playgroud)

因此,当用户选择汽车类型时,我将使用采用 CarTypeId(父选定 ID)的 filterCarMakes 管道过滤第二个下拉列表。这一切都很好。这是我的filterCarMakes管子。

@Pipe({
    name: 'filterCarMakes',
    pure: false
})
export class FilterMakesPipe implements PipeTransform {
    transform(carMakesOptions: CarMakeSelectItem[], carTypeId: string): CarMakeSelectItem[] {
        if (!carTypeId)
            return carMakesOptions.filter(p => p.carTypeId == null);
        //perform some filtering operation
        return filteredCarMakeOptions;
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是,如果我将 console.log 放入管道中,它会继续非常快速地在控制台上记录该消息(例如每 100 毫秒一次),这意味着即使 parent 的值没有更改,它也会继续调用。这样做的副作用是,如果有滚动,我无法在子下拉列表中选择任何值,因为它会继续刷新选项。

过滤下拉列表的简单屏幕截图如下(它不会让我滚动选择其他值并会继续刷新)

在此处输入图片说明

PS:我不想在 onChange 事件中执行它并从组件调用管道,那么是否可以在模板中执行它?

Ana*_*dan 1

发生这种情况是因为管道不纯净

纯管道:Angular 仅在检测到输入值的纯更改时才执行纯管道。纯粹的更改是对原始输入值(字符串、数字、布尔值、符号)的更改或更改的对象引用(日期、数组、函数、对象)。

不纯管道:Angular 在每个组件更改检测周期期间执行不纯管道。不纯的管道被频繁调用,就像每次击键或鼠标移动一样频繁。

来源: https: //angular.io/guide/pipes

但如果您确实需要管道因任何原因而变得不纯,出于性能考虑,您需要将组件的changeDetection策略设置为OnPush,并在应用更改时手动触发更改检测。

import { Component, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';

@Component({
  selector: 'awesome-component',
  templateUrl: './pda.html',
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class AwesomeComponent implements OnInit {
  constructor(
    private cd: ChangeDetectorRef,
  ) { }

  ...

  fetchData() {
    ...
    // after any data change
    this.cd.markForCheck();
    ...
  }
  ...
}
Run Code Online (Sandbox Code Playgroud)