Angular克隆数组会自动更改

时间:2017-12-25 16:36:36

标签: arrays angular clone

我希望根据可用复选框中的活动状态设置过滤器。

首先应该显示所有内容,在选择过滤器之后,在这种情况下,选择的英雄名称应该只显示包含至少名称的英雄。

有趣的是:如果我尝试将值更改回" 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>

3 个答案:

答案 0 :(得分:2)

如果要将数组this.fullHeroes的克隆复制到数组this.heroes中,请使用:

this.heroes = JSON.parse(JSON.stringify(this.fullHeroes));

这样您就可以将数组this.fullHeroes的完整副本复制到this.heroes,然后this.heroes中的更改不会影响其他数组。

答案 1 :(得分:0)

    <div align="center" class="AddTodoBox" [hidden]="todoService.showAddTodoBox">
  <h4>Add New Todo</h4>
  <form (ngSubmit)="AddTodo(todo);todoForm.reset()" #todoForm="ngForm">
  <div class="form-group">
    <label for="todoText">Todo:</label>
    <input type="text" [(ngModel)]="todo.todoText" #todotext="ngModel" class="form-control" name="todoText" id="todoText" required />
    <div [hidden]="todotext.valid || todotext.pristine"
         class="alert alert-danger">
      Todo is required
    </div>
  </div>
  <div class="form-group">
    <label for="todoDesc">Description:</label>
    <input type="text" class="form-control" [(ngModel)]="todo.todoDesc" #tododesc="ngModel" name="todoDesc" id="todoDesc" required />
    <div [hidden]="tododesc.valid || tododesc.pristine"
         class="alert alert-danger">
      Description is required
    </div>
  </div>
<button type="submit" [disabled]="!todoForm.form.valid" class="btn btn-success btn-block">Submit</button>
</form>
</div>
<div *ngIf="todos && todos.length > 0" class="TodoListBox">
  <h2 align="center">Your Todo's List</h2>
  <table id="mytable" class="table table-bordred table-striped">
<thead>
                    <th>Todo</th>
                      <th>View</th>
                       <th>Edit</th>
                      <th>Delete</th>
                    </thead>
     <tbody>
<tr *ngFor="let todo of todos">
     <td>{{todo.todoText}}</td>
     <td><a  [routerLink]="['/todo', todo._id]" title="Click to Open {{todo.todoText}}">View</a></td>
     <td><p data-placement="top" data-toggle="tooltip" title="Edit"><button class="btn btn-primary btn-xs" (click) = "showEditTodo(todo)" data-title="Edit" data-toggle="modal" data-target="#edit" ><span class="glyphicon glyphicon-pencil"></span></button></p></td>
     <td><p data-placement="top" data-toggle="tooltip" title="Delete"><button class="btn btn-danger btn-xs" (click) = "showDeleteTodo(todo)" data-title="Delete" data-toggle="modal" data-target="#delete" ><span class="glyphicon glyphicon-trash"></span></button></p></td>
     </tr>
<tr>
  </tbody>
  </table>
  <!-- Edit Modal -->
  <div class="modal fade" id="edit" role="dialog">
    <div class="modal-dialog modal-md">
      <div class="modal-content">
        <div class="modal-header">
          <button type="button" class="close" data-dismiss="modal">&times;</button>
          <h4 class="modal-title">Edit Todo</h4>
        </div>
        <div class="modal-body">
          <div align="center" class="EditTodoBox">
            <form (ngSubmit)="EditTodo(todoToEdit)" #editTodoForm="ngForm">
            <div class="form-group">
              <label for="todoText">Todo:</label>
              <input type="text" [(ngModel)]="todoToEdit.todoText" #todoedittext="ngModel" class="form-control" name="todoText" id="todoText" required />
              <div [hidden]="todoedittext.valid || todoedittext.pristine"
                   class="alert alert-danger">
                Todo is required
              </div>
            </div>
            <div class="form-group">
              <label for="todoDesc">Description:</label>
              <textarea class="form-control" [(ngModel)]="todoToEdit.todoDesc" #todoeditdesc="ngModel" name="todoDesc" id="todoDesc" required></textarea>
              <div [hidden]="todoeditdesc.valid || todoeditdesc.pristine"
                   class="alert alert-danger">
                Description is required
              </div>
            </div>
<button type="submit" [disabled]="!editTodoForm.form.valid || !editTodoForm.form.dirty" class="btn btn-success btn-block">Submit</button>
          </form>
          <div style="margin:10px;" *ngIf="apiMessage" align="center" class="alert alert-success" role="alert">
          <strong>{{apiMessage}}</strong>
          </div>
          </div>
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        </div>
      </div>
    </div>
  </div>
<!-- Delete Modal -->
  <div class="modal fade" id="delete" role="dialog">
    <div class="modal-dialog modal-md">
      <div class="modal-content">
        <div class="modal-header">
          <button type="button" class="close" data-dismiss="modal">&times;</button>
          <h4 class="modal-title">Delete Todo</h4>
        </div>
        <div class="modal-body">
          <div align="center" class="DeleteTodoBox">
            <div *ngIf="!apiMessage" align="center" class="alert alert-danger" role="alert">
              <p>Are you sure want to delete this todo?</p>
            <strong>{{todoToDelete.todoText}}</strong>
            </div>
          <div style="margin:10px;" *ngIf="apiMessage" align="center" class="alert alert-success" role="alert">
          <strong>{{todoToDelete.todoText}}</strong>  {{apiMessage}}
          </div>
          </div>
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-danger" *ngIf="!apiMessage" (click)="DeleteTodo(todoToDelete)">Confirm</button>
          <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        </div>
      </div>
    </div>
  </div>
</div>
<div *ngIf="todos.length <= 0" class="NoTodosBox">
<div align="center" class="alert alert-info" role="alert">
<strong>No Todos Available in Database</strong>
</div>
</div>

执行该行之后,每次你改变英雄时,你也会改变fullHeroes,因为它们都引用同一个数组。你需要复制fullHeroes。

请注意,您在使用this.heroes = this.fullHeroes 时滥用map()。你正在使用一个循环,你可以使用forEach()

答案 2 :(得分:0)

您可以使用TypeScript {{3}}运算符克隆数组:

const a1 = [1, 2, 3, 4, 5, 6];
const a2 = [...a1];