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

标签 angular primeng angular-pipe

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

因此,当用户选择汽车类型时,我使用 filterCarMakes 管道过滤第二个下拉列表,该管道采用 CarTypeId(父选择的 ID)。一切都很好。这是我的 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;
    }
}

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

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

enter image description here

P.S:我不想在 onChange 事件中执行它并从组件调用管道,所以可以在模板中执行吗?

最佳答案

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

Pure pipes: Angular executes a pure pipe only when it detects a pure change to the input value. A pure change is either a change to a primitive input value (String, Number, Boolean, Symbol) or a changed object reference (Date, Array, Function, Object).

Impure pipes: Angular executes an impure pipe during every component change detection cycle. An impure pipe is called often, as often as every keystroke or mouse-move.

来源: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();
    ...
  }
  ...
}

关于angular - 如何仅在值更改时调用管道,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45396411/

相关文章:

css - 如何更改嵌套 Accordion 中特定 Accordion 的背景颜色?

angular - 如何禁用 TurboTable 组件上取消选择行的选项?

javascript - 找不到管道 : Angular 5 custom pipe

angular - 为什么我在 PrimeNG FileUpload 组件中遇到与引用不存在页面的 url 参数相关的问题

Angular 4 观察两种方式绑定(bind)属性的变化

css - 如何将当前标签实例传递给angular2中的事件

angular - 路由总是重新加载页面

angular - 将管道的结果声明为局部变量

angular - 指定值无法解析,或使用数字管道时超出范围

javascript - TypeScript 类 - 将对象数组声明为属性