当 ngfor 循环中的数据 bing 时 angular 中的错误
bug in angular when data bing inside ngfor loop
为什么我每次使用 ngFor 时,循环都会运行 4 次?以及如何阻止它?有人可以向我解释发生了什么吗?
here是一个小样本。
iShouldrepeatOneTime
方法被调用4次的原因是Angular默认的ChangeDetectionStrategy。默认情况下,每次组件发生变化时,在这种情况下,对于每个循环,Angular 都会检查整个组件是否有变化。 Angular 知道 iShouldrepeatOneTime
的 return 值是否改变的唯一方法是调用它。
那么你如何解决这个问题呢?我想到了两个选择:
- 使用
OnPush
ChangeDetectionStrategy,或
- 确保您不会出于事件发射器以外的原因绑定到模板中的方法。而是绑定到属性。
我将扩展第二点。假设您的组件 someValue
中有一个 属性 和一个方法 calculateSomeValue()
,如下所示:
someValue = 'foo';
calculateSomeValue(): string {
return 'bar';
}
在您的模板中,{{ someValue }}
比 {{ calculateSomeValue() }}
更有效,因为在前一种方法中 Angular 已经知道 属性 的值是否已更改以及是否它需要在视图中更新。在后一种方法中,Angular需要先调用该方法,然后才知道是否需要更新视图中的值。
这里没有错误!你有 4 个输出,因为你的数组有 4 个对象。如果要按特定字段迭代值,可以 add pipe:
1) 将此管道添加到 app.component
的末尾
import { Pipe, PipeTransform } from "@angular/core";
@Pipe({
name: "mymap"
})
export class ArrayMapPipe implements PipeTransform {
transform(array: any, field: string): any[] {
if (!Array.isArray(array)) {
return;
}
return array.filter((e: any) => e.camp2 === field);
}
}
2) 将管道导入 app.module
import { AppComponent, ArrayMapPipe } from './app.component';
...
declarations: [ AppComponent, HelloComponent, ArrayMapPipe ]
3) 你可以这样使用它:
<div *ngFor="let key of array | mymap:'orange'">
<div>
<span class="teste">{{key | json}} </span>
</div>
</div>
这不是 Bug。在值绑定中使用函数调用不是好的做法。在这种情况下,每次 Angular 运行变化检测时都会调用函数。
您应该按如下方式进行。
<div>{{ someValue }}</div>
export class AppComponent {
someValue;
ngOnInit() {
this.someValue = this.someMethod();
}
someMethod(){
const someValue = 2;
return someValue;
}
}
为什么我每次使用 ngFor 时,循环都会运行 4 次?以及如何阻止它?有人可以向我解释发生了什么吗?
here是一个小样本。
iShouldrepeatOneTime
方法被调用4次的原因是Angular默认的ChangeDetectionStrategy。默认情况下,每次组件发生变化时,在这种情况下,对于每个循环,Angular 都会检查整个组件是否有变化。 Angular 知道 iShouldrepeatOneTime
的 return 值是否改变的唯一方法是调用它。
那么你如何解决这个问题呢?我想到了两个选择:
- 使用
OnPush
ChangeDetectionStrategy,或 - 确保您不会出于事件发射器以外的原因绑定到模板中的方法。而是绑定到属性。
我将扩展第二点。假设您的组件 someValue
中有一个 属性 和一个方法 calculateSomeValue()
,如下所示:
someValue = 'foo';
calculateSomeValue(): string {
return 'bar';
}
在您的模板中,{{ someValue }}
比 {{ calculateSomeValue() }}
更有效,因为在前一种方法中 Angular 已经知道 属性 的值是否已更改以及是否它需要在视图中更新。在后一种方法中,Angular需要先调用该方法,然后才知道是否需要更新视图中的值。
这里没有错误!你有 4 个输出,因为你的数组有 4 个对象。如果要按特定字段迭代值,可以 add pipe:
1) 将此管道添加到 app.component
的末尾import { Pipe, PipeTransform } from "@angular/core";
@Pipe({
name: "mymap"
})
export class ArrayMapPipe implements PipeTransform {
transform(array: any, field: string): any[] {
if (!Array.isArray(array)) {
return;
}
return array.filter((e: any) => e.camp2 === field);
}
}
2) 将管道导入 app.module
import { AppComponent, ArrayMapPipe } from './app.component';
...
declarations: [ AppComponent, HelloComponent, ArrayMapPipe ]
3) 你可以这样使用它:
<div *ngFor="let key of array | mymap:'orange'">
<div>
<span class="teste">{{key | json}} </span>
</div>
</div>
这不是 Bug。在值绑定中使用函数调用不是好的做法。在这种情况下,每次 Angular 运行变化检测时都会调用函数。 您应该按如下方式进行。
<div>{{ someValue }}</div>
export class AppComponent {
someValue;
ngOnInit() {
this.someValue = this.someMethod();
}
someMethod(){
const someValue = 2;
return someValue;
}
}