【问题标题】:Why array functions like 'filter' and 'map' doesn't work in 'ngFor' expression of Angular?为什么像'filter'和'map'这样的数组函数在Angular的'ngFor'表达式中不起作用?
【发布时间】:2017-11-23 10:38:13
【问题描述】:

在使用 Angular 模板时,我发现像 slice() 这样的数组函数与 ngFor 这样的指令表达式配合得非常好

<div *ngFor="let item of arry.slice(3)">
  {{ item.name }}
</div>

当我尝试在 ngFor 表达式中使用 filter()map() 之类的数组函数时,如下所示

<div *ngFor="let item of arry.filter(i => i.marks > 40)">
  {{ item.name }}
</div>

它给了我角度模板解析错误

Zone: <root> ; Task: Promise.then ; Value: Error: Template parse errors: Parser Error: Bindings cannot contain assignments at column 25 in [let item of arry.filter(i => i.marks > 40)]

为了了解这种行为背后的原因,我试图找出一些解释这些限制的文件,但没有找到。任何线索或解释将不胜感激。

【问题讨论】:

  • 不是所有的打字稿表达式都允许在一个角度模板中,例如,创建一个新的匿名函数
  • 这在所有浏览器上都失败了吗?
  • 是的,这是一个模板错误。严格不允许有角度的。这不是浏览器限制
  • 我会从这里开始阅读:angular.io/guide/template-syntax#template-expressions 我喜欢让我的模板尽可能简单,并在 TypeScript 代码中完成所有业务逻辑。
  • @Skeptor,它无法解析该文本并认为等号是一个赋值。

标签: javascript arrays angular ngfor


【解决方案1】:

正如 cmets 中提到的,Angular 对模板中允许的表达式类型非常严格。这有充分的理由:例如,涉及函数调用的复杂表达式不能很好地与更改检测配合使用。请记住,这些表达式实际上并不是 JavaScript/TypeScript;它们只是 JavaScript-类似

如果你真的想在模板中做这个过滤,那么

<div *ngFor="let item of arry">
  <ng-container *ngIf="item.marks > 40">
    {{ item.name }}
  </ng-container>
</div>

另一种选择是编写一个管道来进行过滤。但是,Angular 团队也建议不要这样做。

一般来说,更复杂的逻辑可以而且应该写在你的组件中的 TS 逻辑中。

顺便说一句,对于slice,建议使用slice pipe。 Angular 将能够比 .slice() 更好地优化这一点。

有些相关:Support arrow functions in template syntax

【讨论】:

  • "...另一种选择是编写一个管道来进行过滤。但是,Angular 团队也建议不要这样做..." 这是否意味着 ppl不应该使用管道吗?另外,在文档中哪里可以找到它?
  • 不,这意味着您不应该使用管道进行排序和过滤。见angular.io/guide/pipes#appendix-no-filterpipe-or-orderbypipe
  • 很好的资源,不知道将管道用于这些目的是一种不好的做法。感谢您的链接
  • 如果我制作一个自定义管道 pure 用于过滤呢?为什么一定是不纯的?
猜你喜欢
  • 1970-01-01
  • 2020-10-07
  • 2019-10-28
  • 2022-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-15
相关资源
最近更新 更多