【问题标题】:Angular generic pipe角通用管道
【发布时间】:2018-03-09 15:05:09
【问题描述】:

我想写通用的pipe。这是我为数据类型Category编写的pipe

order-by-category.ts

import { Pipe, PipeTransform } from '@angular/core';
import { Category } from '../../models/Category';
import { sortBy } from 'lodash';


@Pipe({
  name: 'orderByCategory',
})
export class OrderByCategoryPipe implements PipeTransform {
  transform(value: Category[]): Category[] {
    return sortBy(value, (o: Category) => { return o.name; });
  }
}

.html

 <ion-item *ngFor="let c of categorySortedList | orderByCategory">
      <ion-label>{{c.name }}</ion-label>
      <ion-radio [value]="c.id" (ionSelect)="selectedCategory(c)"></ion-radio>
 </ion-item>

现在我需要写同样的pipe。但data type 不同。

现在是这样的:

 transform(value: BudgetGroup[]): BudgetGroup[] {
    return sortBy(value, (o: BudgetGroup) => { return o.name; });
  }

所以我想在这里使用通用解决方案而不是同一种 2 pipes 并且我也需要维护 Typed pipe

【问题讨论】:

  • Category 替换为{ name: string } 不起作用?
  • 我还没有在这里尝试任何东西。希望您将您的建议作为答案提供更多详细信息? @Rob
  • 好吧,在这里提出问题之前,您绝对应该自己尝试一些事情..
  • 其实specific pipe上面我已经写过了。之后,我不知道如何将其转换为generic one.@Rob
  • 我看不出你的建议和这里的any (no type) 有什么区别。你的想法? @Rob

标签: angular typescript ionic3


【解决方案1】:

我在这里提出了一个类似的问题:A way to cast variables in template to multiple types,由于我在网上搜索时浏览了这个帖子 10 次,所以我也想在这里发布一个 hacky 解决方案。

我做了以下简单的管道:


@Pipe({   name: 'toType',   pure: true, }) export class ToTypePipe
implements PipeTransform {   transform<T>(value: unknown, _: T): T {
    return value as T;   } }

你可以这样称呼它

value | toType: Animal.DOG

value 可以是 Animal 的任何值,但我们只是将 is 作为其中之一 值,所以编译器认为可以使用它,不要抱怨。

这是不安全的,有点删除严格模式的目的。

但是,它允许做一些变通方法并制作一些非常简单的演员表 简单。就像在这种情况下:

[cdkColumnDef]="columns.name.def">   <td class="align-items-center p-4
w-80" cdk-cell *cdkCellDef="let element">  ```

`*cdkCellDef="let element"` this IS an `Animal` but angular template
do not allow us to have the correct typing, so in this case `let
element | typeOf: Animal.DOG` should be completely safe

【讨论】:

    【解决方案2】:

    我只是在写相同的内容并找到了您的问题。答案很明显——通用函数会起作用:

    @Pipe({
      name: 'orderByName',
    })
    export class OrderByNamePipe implements PipeTransform {
      transform<T extends {name: string}>(value: T[]): T[] {
        return value.sort((a, b) => {
          if (a.name > b.name) return -1;
          if (a.name < b.name) return 1;
          return 0;
        });
      }
    }
    

    原始类型被保留并在模板中查看?

    【讨论】:

    • 使用此解决方案在字符串模式下模板会报错。
    【解决方案3】:

    试图用代码澄清@Rob 已经指出的内容。您可以概括管道的 transform() 方法以符合具有这样强制“名称”的特定类型。

    import { Pipe, PipeTransform } from '@angular/core';
    import { sortBy } from 'lodash';
    
    export interface NameModelForPipe {
     name: string; // forces the 'name' property
     [key: string]: any; // allows for basically another property of 'any' type
    }
    
    @Pipe({
      name: 'orderByNameModel',
    })
    export class OrderByNameModelPipe implements PipeTransform {
      transform(value: NameModelForPipe[]): NameModelForPipe[] {
        return sortBy(value, (o: NameModelForPipe) => { return o.name; });
      }
    }
    

    如果你不想显式声明一个接口,你可以直接指定它,

    import { Pipe, PipeTransform } from '@angular/core';
    import { sortBy } from 'lodash';
    
    
    @Pipe({
      name: 'orderByNameModel',
    })
    export class OrderByNameModelPipe implements PipeTransform {
      transform(value: { name: string; [key: string]: any; }[]): { name: string; [key: string]: any; }[] {
        return sortBy(value, (o: { name: string; [key: string]: any; }) => { return o.name; });
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-12
      • 1970-01-01
      • 2017-02-23
      • 1970-01-01
      • 2020-07-23
      • 1970-01-01
      • 2018-07-13
      • 1970-01-01
      相关资源
      最近更新 更多