在ngIf中使用array.prototype.some

Con*_*ver 2 arrays any angular-ng-if angular

我正在使用第8版开发有角度的应用程序。在ngIf表达式内部,我想检查数组中是否存在存在。所以我写了下面的表达式:

*ngIf="questionniare.factors.some(item => item.intensities.length > 0)"
Run Code Online (Sandbox Code Playgroud)

但是现在我在控制台窗口中收到此错误:

解析器错误:绑定不能包含[questionniare.factors.some(item => item.intensities.length> 0)]中第34列的赋值

但是,正如我所见,我的状况没有任何任务。那么有什么问题,我该如何解决?

(我知道我可以定义一个方法并在该方法内完成这项工作,但是我想知道这是否对ngIf有限制,我下次应该考虑一下吗?)

Con*_*Fan 9

错误消息提到了“赋值”,但问题是您正在组件模板内部创建箭头函数,这是不允许的。GitHub 上发布了一个功能请求,要求支持在 Angular 模板中创建这些功能。

为了Array.prototype.some在模板中使用,您必须在组件代码中定义谓词:

// You can define the predicate as a method
public itemHasIntensities(item): boolean {
  return item => item.intensities.length > 0;
}

// You can also define the predicate as an arrow function
public itemHasIntensities = (item): boolean => item.intensities.length > 0;
Run Code Online (Sandbox Code Playgroud)

并将该函数作为参数传递Array.prototype.some给模板:

*ngIf="questionniare.factors.some(itemHasIntensities)"
Run Code Online (Sandbox Code Playgroud)

此 stackblitz类似于您的原始代码并给出相同的错误。另一个 stackblitz展示了相同的示例,其中包含在组件代码中定义的回调函数。


话虽如此,正如问题中所提到的,最简单的解决方案是在组件方法中评估整个条件:

public showElement(): boolean {
  return this.questionniare.factors.some(item => item.intensities.length > 0);
}
Run Code Online (Sandbox Code Playgroud)
*ngIf="showElement()"
Run Code Online (Sandbox Code Playgroud)

注意:建议记住该函数以避免性能问题。


小智 6

问题是绑定正在列表上进行迭代并跟踪在后台分配的值。

有两种解决方案,首先是将您的逻辑放在执行此操作的组件类的公共方法中,这是两种解决方案中较慢的一种,因为每次运行更改检测都会检查您的数组值。

更好的解决方案是每当数组更改时更新组件上的值

您可以这样做:

@Component({
  selector: 'my-component',
  templateUrl: 'my-component.html',
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class MyComponent {
  @Input()
  set questionaire(value: Questionaire) {
    this.questionaire$.next(value);
  }

  readonly questionaire$ = new ReplaySubject<Questionaire>(1);
  readonly hasIntensities$ = this.questionaire$.pipe(
    map(questionaire => questionniare.factors.some(item => item.intensities.length > 0))
  );
};
Run Code Online (Sandbox Code Playgroud)

然后,您可以在模板中执行以下操作: *ngIf="hasIntensities$ | async"

您也可以通过更改检测器ref和ngOnChanges完成此操作,但这应该是最有效的方法

  • 我不确定这是他的要求-他可以做很多事情来解决特定问题-问题是ngIf指令中使用数组纯方法是否存在限制 (2认同)