2
votes

this.students.splice (index, 1) ne change pas dans l'interface utilisateur [Angular]

J'essaie de supprimer un objet étudiant que j'ai dans un tableau étudiants dans mon composant parent. L'élève est supprimé en transmettant son nom à la méthode. Cependant, la vue n'est pas mise à jour. Voici mon code pour la méthode de suppression utilisant splice

<h2>UnderGrads</h2>
<div>
  <ul>
    <li *ngFor="let x of studentList">
      {{ x }} <button (click)="delete(x)">X</button>
    </li>
  </ul>
</div>

Voici le code complet de la classe parente:

import { Component, OnInit, Input, EventEmitter, Output } from "@angular/core";
import { student } from "../../student";

@Component({
  selector: "app-under-grads",
  templateUrl: "./under-grads.component.html",
  styleUrls: ["./under-grads.component.css"]
})
export class UnderGradsComponent implements OnInit {
  @Input() public studentList;
  @Output() public childEvent = new EventEmitter();

  constructor() {}

  ngOnInit() {
    console.log(this.studentList);
  }

  sendInfo() {
    this.childEvent.emit("Hello I am sending this to the parent");
  }

  @Output() public studentDeletion = new EventEmitter<string>();
  delete(name: string) {
    //  console.log("delete it");
    this.studentDeletion.emit(name);
    console.log(name);
  }
}

Voici le code du composant HTML du parent:

<h1>{{ txt }}</h1>
<app-under-grads
  (childEvent)="txt = $event"
  [studentList]="undergradsList"
  (studentDeletion)="deleteStudent($event)"
>
</app-under-grads>

Voici le code de mon composant enfant:

import { Component, OnInit } from "@angular/core";
import { student } from "../../student";

@Component({
  selector: "app-students",
  templateUrl: "./students.component.html",
  styleUrls: ["./students.component.css"]
})
export class StudentsComponent implements OnInit {
  students: student[] = [
    { name: "Marwa", level: "undergrad" },
    { name: "Heba", level: "undergrad" },
    { name: "Amal", level: "postgrad" }
  ];

  txt = "";
  toBeDeleted: student;

  public undergradsList = this.undergrads();
  constructor() {}

  ngOnInit() {
    this.undergrads();
    console.log(this.undergrads);
  }
  undergrads() {
    var Arrayres = new Array();
    for (var i = 0; i < this.students.length; i++) {
      if (this.students[i].level === "undergrad") {
        Arrayres.push(this.students[i].name);
      }
    }
    console.log(Arrayres);
    return Arrayres;
  }
  deleteStudent(name: string) {
    for (var x = 0; x < this.students.length; x++) {
      if (this.students[x].name === name) {
        this.students.splice(x, 1);
        this.students = [...this.students];
        this.undergradsList = this.undergrads();
        console.log(x);
        return;
      }
    }
    // const studentIndex = this.students.findIndex(e => e.name === name);

    console.log("hi delte");
  }
}

Voici le HTML de mon composant enfant qui est rendu à l'écran. studentList est un tableau de chaînes de noms

 deleteStudent(name: string) {
    for (var x = 0; x < this.students.length; x++) {
      if (this.students[x].name === name) {
        this.students.splice(x, 1);
        this.students = [...this.students];
        console.log(x);
        return;
      }
    }}


8 commentaires

Je viens d'essayer ce code et cela a fonctionné pour moi ... mais cela semble être plus de lignes de code que ce dont vous auriez besoin pour cela. (Je vois que certains ont déjà suggéré des alternatives comme réponses ci-dessous.) J'ai un stackblitz ici: stackblitz.com/ modifier / angular-moelmv


Note de programmation rapide: si vous supprimez des éléments de l'élément sur lequel vous itérez, commencez à la fin, pas au début car la suppression d'éléments de l'arrière lorsque vous vous déplacez vers l'avant ne modifie les pièces que vous n'avez pas encore traitées. Courir d'avant en arrière va absolument tout gâcher. Cela dit: splice modifie déjà le tableau d'origine. Pourquoi le recréez-vous sur lui-même? Que this.students = [... this.students] n'a aucun sens, le tableau a déjà été réduit de .splice .


x est l'objet entier et vous le comparez au nom.


@DeborahK J'ai ajouté mon fichier HTML. Pouvez-vous me dire si je fais quelque chose de mal dans le code HTML à l'origine du problème?


delete (x.name) dans le HTML résoudra le problème


Oui. Vous faites référence aux mauvais objets. J'ai mis à jour mon stackblitz avec une version corrigée de votre HTML: stackblitz.com/edit/angular-moelmv


Mais vous devez comparer l'objet entier, pas seulement le nom.


Voici un stackblitz mis à jour stackblitz.com/edit/angular -3nhmkw? File = src / app /…


3 Réponses :


1
votes

Vous modifiez le tableau, puis attribuez un nouveau tableau par-dessus. La mutation est mauvaise M'kay!

J'utilise un filtre pour ce genre de suppressions

this.students = this.students.filter(s => student !== s);

Vous comparez le nom à l'objet étudiant complet. Voici un StackBlitz fixe.

https://stackblitz.com/edit/angular-3nhmkw?file=src/app/app.component.ts


1 commentaires

Je ne compare pas un nom à un objet complet. J'ai de nouveau mis à jour ma question



0
votes

Ce n'est pas un problème avec le code de votre composant. Vous devez mettre à jour le code HTML où vous itérez le tableau.

Utilisez simplement trackBy avec votre ngFor.

    <tr *ngFor="let hero of heroes; trackBy: trackHero" >
 <td>{{hero.name}}</td>
 </tr>


trackHero(index, hero) { 
console.log(hero); 
return hero ? hero.id : undefined;
 }

Dans trackHero, vous devez renvoyer un attribut qui est unique dans votre objet.


0 commentaires

1
votes

Je suppose que undergradsList est identique à students

Donc, dans votre fonction deleteStudent

il devrait être comme ça

 deleteStudent(name: string) {
    for (var x = 0; x < this.students.length; x++) {
      if (this.students[x].name === name) {
        this.students.splice(x, 1);
        this.undergradsList = [...this.students];
        console.log(x);
        return;
      }
    }}


0 commentaires