在 ngIf 中使用 array.prototype.some
Using array.prototype.some inside ngIf
我正在使用第 8 版开发 angular 应用程序。在 ngIf
表达式中,我想检查数组中存在的东西。所以我写了下面的表达式:
*ngIf="questionniare.factors.some(item => item.intensities.length > 0)"
但现在我在控制台中收到此错误 window:
Parser Error: Bindings cannot contain assignments at column 34 in
[questionniare.factors.some(item => item.intensities.length > 0)]
但是如你所见,我的情况下没有任何作业。那么问题是什么,我该如何解决?
(我知道我可以定义一个方法并在该方法中完成这项工作,但我想知道这是否是我下次应该考虑的对 ngIf 的限制?)
这没有写在 Angular 文档中,但看起来您不能在结构指令中使用 Array.some
,您应该将此逻辑移动到组件内的特定函数中。
问题在于您的绑定正在遍历列表并跟踪在后台分配的值。
对此有几个解决方案,首先是将您的逻辑放在执行此操作的组件 class 上的 public 方法中,这是两个解决方案中较慢的一个,因为每次都会更改检测运行,它将检查您的数组值。
更好的解决方案是在数组发生变化时更新组件上的值
你可以这样做:
@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))
);
};
然后在模板中你可以这样做:
*ngIf="hasIntensities$ | async"
您也可以通过更改检测器 ref 和 ngOnChanges 来完成它,但这应该是最有效的方法
错误消息提到 "assignment" 但问题是您正在组件模板内创建箭头函数,这是不允许的。 feature request 已在 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;
并将该函数作为参数传递给模板中的 Array.prototype.some
:
*ngIf="questionniare.factors.some(itemHasIntensities)"
This stackblitz is similar to your original code and gives the same error. This other stackblitz 显示了组件代码中定义的回调函数的相同示例。
也就是说,正如问题中提到的,最简单的解决方案是在组件方法中评估整个条件:
public showElement(): boolean {
return this.questionniare.factors.some(item => item.intensities.length > 0);
}
*ngIf="showElement()"
注意:建议记忆函数以避免性能问题。
我正在使用第 8 版开发 angular 应用程序。在 ngIf
表达式中,我想检查数组中存在的东西。所以我写了下面的表达式:
*ngIf="questionniare.factors.some(item => item.intensities.length > 0)"
但现在我在控制台中收到此错误 window:
Parser Error: Bindings cannot contain assignments at column 34 in [questionniare.factors.some(item => item.intensities.length > 0)]
但是如你所见,我的情况下没有任何作业。那么问题是什么,我该如何解决?
(我知道我可以定义一个方法并在该方法中完成这项工作,但我想知道这是否是我下次应该考虑的对 ngIf 的限制?)
这没有写在 Angular 文档中,但看起来您不能在结构指令中使用 Array.some
,您应该将此逻辑移动到组件内的特定函数中。
问题在于您的绑定正在遍历列表并跟踪在后台分配的值。
对此有几个解决方案,首先是将您的逻辑放在执行此操作的组件 class 上的 public 方法中,这是两个解决方案中较慢的一个,因为每次都会更改检测运行,它将检查您的数组值。
更好的解决方案是在数组发生变化时更新组件上的值
你可以这样做:
@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))
);
};
然后在模板中你可以这样做:
*ngIf="hasIntensities$ | async"
您也可以通过更改检测器 ref 和 ngOnChanges 来完成它,但这应该是最有效的方法
错误消息提到 "assignment" 但问题是您正在组件模板内创建箭头函数,这是不允许的。 feature request 已在 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;
并将该函数作为参数传递给模板中的 Array.prototype.some
:
*ngIf="questionniare.factors.some(itemHasIntensities)"
This stackblitz is similar to your original code and gives the same error. This other stackblitz 显示了组件代码中定义的回调函数的相同示例。
也就是说,正如问题中提到的,最简单的解决方案是在组件方法中评估整个条件:
public showElement(): boolean {
return this.questionniare.factors.some(item => item.intensities.length > 0);
}
*ngIf="showElement()"
注意:建议记忆函数以避免性能问题。