Angular 克隆的数组自动更改
Angular cloned array gets changed automatically
我想要一个基于可用复选框的活动状态的过滤器。
首先应该显示所有内容,在选择过滤器之后,在这种情况下,选择的英雄名称应该只显示至少包含名称的英雄。
有趣的部分是:如果我尝试将值更改回 "full"-object,它不会获取完整的对象,而是它的更改版本。
我不知道那里发生了什么。因为我只在应用程序的构造函数中初始化了完整对象。对于完整对象,我的意思是 fullHeroes。
App.Component.ts :
import { Component, OnInit } from '@angular/core';
interface Hero {
name: string;
}
@Component({
selector: 'app-root',
templateUrl: './app.component.html'
})
export class AppComponent {
readonly fullHeroes: Hero[] = [];
heroes: Hero[] = [];
constructor() {
this.heroes.push(
{ name: 'Bob' }, { name: 'Alice' }, { name: 'Mallory' }
);
this.fullHeroes = this.heroes.slice(0);
}
filter(name, checked) {
if (checked) {
for (let i = 0; i <= this.heroes.length; i++) {
let found = false;
const currentHero = this.heroes[i];
if (currentHero && currentHero.name === name) {
found = true;
}
if (found) {
this.heroes.splice(i, 1);
}
}
} else {
this.heroes = [];
this.heroes = this.fullHeroes;
}
return;
}
}
App.component.html :
<div class="container">
<h1>World of Heroes</h1>
<p>Filter your Heroes based on names!</p>
<div class="filter">
<form #heroForm="ngForm">
<fieldset>
<legend>Choose the names</legend>
<div class="form-check" *ngFor="let hero of heroes">
<label class="form-check-label">
<input class="form-check-input" type="checkbox" [name]="hero.name" (change)="filter($event.target.name, $event.target.checked)"> {{hero.name}}
</label>
</div>
</fieldset>
</form>
</div>
<hr>
<h2>Results:</h2>
<div class="row result-list">
<div class="col-md-4 hero" *ngFor="let hero of heroes">
<h3>Name: {{hero.name}}</h3>
</div>
</div>
</div>
this.heroes = this.fullHeroes
执行该行后,每次改变 heroes 时,也会改变 fullHeroes,因为它们都引用同一个数组。您需要复制一份 fullHeroes。
请注意,您在应该使用 forEach()
的地方滥用了 map()
。你正在使用一个循环,你可以在其中使用 some()
.
如果要将数组 this.fullHeroes
复制到数组 this.heroes
中,请使用:
this.heroes = JSON.parse(JSON.stringify(this.fullHeroes));
这样你就可以将数组 this.fullHeroes
完整复制到 this.heroes
中,然后 this.heroes
中的更改不会影响另一个数组。
您可以使用 TypeScript spread 运算符克隆数组:
const a1 = [1, 2, 3, 4, 5, 6];
const a2 = [...a1];
我想要一个基于可用复选框的活动状态的过滤器。
首先应该显示所有内容,在选择过滤器之后,在这种情况下,选择的英雄名称应该只显示至少包含名称的英雄。
有趣的部分是:如果我尝试将值更改回 "full"-object,它不会获取完整的对象,而是它的更改版本。
我不知道那里发生了什么。因为我只在应用程序的构造函数中初始化了完整对象。对于完整对象,我的意思是 fullHeroes。
App.Component.ts :
import { Component, OnInit } from '@angular/core';
interface Hero {
name: string;
}
@Component({
selector: 'app-root',
templateUrl: './app.component.html'
})
export class AppComponent {
readonly fullHeroes: Hero[] = [];
heroes: Hero[] = [];
constructor() {
this.heroes.push(
{ name: 'Bob' }, { name: 'Alice' }, { name: 'Mallory' }
);
this.fullHeroes = this.heroes.slice(0);
}
filter(name, checked) {
if (checked) {
for (let i = 0; i <= this.heroes.length; i++) {
let found = false;
const currentHero = this.heroes[i];
if (currentHero && currentHero.name === name) {
found = true;
}
if (found) {
this.heroes.splice(i, 1);
}
}
} else {
this.heroes = [];
this.heroes = this.fullHeroes;
}
return;
}
}
App.component.html :
<div class="container">
<h1>World of Heroes</h1>
<p>Filter your Heroes based on names!</p>
<div class="filter">
<form #heroForm="ngForm">
<fieldset>
<legend>Choose the names</legend>
<div class="form-check" *ngFor="let hero of heroes">
<label class="form-check-label">
<input class="form-check-input" type="checkbox" [name]="hero.name" (change)="filter($event.target.name, $event.target.checked)"> {{hero.name}}
</label>
</div>
</fieldset>
</form>
</div>
<hr>
<h2>Results:</h2>
<div class="row result-list">
<div class="col-md-4 hero" *ngFor="let hero of heroes">
<h3>Name: {{hero.name}}</h3>
</div>
</div>
</div>
this.heroes = this.fullHeroes
执行该行后,每次改变 heroes 时,也会改变 fullHeroes,因为它们都引用同一个数组。您需要复制一份 fullHeroes。
请注意,您在应该使用 forEach()
的地方滥用了 map()
。你正在使用一个循环,你可以在其中使用 some()
.
如果要将数组 this.fullHeroes
复制到数组 this.heroes
中,请使用:
this.heroes = JSON.parse(JSON.stringify(this.fullHeroes));
这样你就可以将数组 this.fullHeroes
完整复制到 this.heroes
中,然后 this.heroes
中的更改不会影响另一个数组。
您可以使用 TypeScript spread 运算符克隆数组:
const a1 = [1, 2, 3, 4, 5, 6];
const a2 = [...a1];