web-dev-qa-db-fra.com

comment actualiser la page après la suppression dans angular5

Je faisais une application de magasinage moyen (Angular 5). J'ai créé un composant de produit de gestion avec une liste de tous les produits et un bouton de suppression. Le bouton Supprimer fonctionne mais le produit est répertorié dans le tableau jusqu'à présent car il a été supprimé de la base de données. Donc, je me demandais s'il existe un moyen possible de restituer ou d'actualiser le composant après la suppression. J'ai essayé de naviguer vers la même page, mais cela ne fonctionnera pas car angular ne permet pas cela. demande-le.

Mon manage-product.component.ts est: -

import { Component, OnInit } from '@angular/core';
import { ProductManageService, ProductDetails } from '../product-manage.service';
import { AllService } from '../all.service';
import { HttpClientModule, HttpClient } from '@angular/common/http';
import { Router } from '@angular/router';
import { Location } from '@angular/common';

@Component({
  selector: 'app-manage-product',
  templateUrl: './manage-product.component.html',
  styleUrls: ['./manage-product.component.css']
})
export class ManageProductComponent implements OnInit{

    prodData : ProductDetails = {
    prodName: '',
    prodPrice: '',
    prodImage: '',
    prodSize: ''
    }

    data: any=[];

  constructor(private add:ProductManageService,
    private router: Router,
    private http:HttpClient,
    private allService :AllService,
    private location : Location) { }

  addProduct(){
    this.add.addProduct(this.prodData).subscribe(()=>{
        console.log("SENT",this.prodData);
    },(err)=>{
        console.log("Error",err);
    })
  }

  delFunc(id){
    // console.log("Delete ",id);
    this.add.deleteProd(id);
    this.router.navigateByUrl("/reload");
  }

  ngOnInit() {

    this.allService.getAlldata().subscribe(data =>{
      console.log("data",data);
      this.data = data;
    });

    console.log(this.data);


}

}

Mon fichier html pour gérer le composant est: -

    <div class="container">

    <form (submit)="addProduct()">
      <div class="form-group">
        <label for="name">Product Name</label>
        <input name="prodName" type="text" class="form-control" id="name" placeholder="Tshirt" [(ngModel)]="prodData.prodName">
      </div>
      <div class="form-group">
        <label for="price">Price</label>
        <input name="prodPrice" type="text" class="form-control" id="price" placeholder="1.1" [(ngModel)]="prodData.prodPrice">
      </div>
      <div class="form-group">
        <label for="image">Price</label>
        <input name="prodImage" type="text" class="form-control" id="image" placeholder="Link to image" [(ngModel)]="prodData.prodImage">
      </div>
      <div class="form-group">
        <label for="size">Price</label>
        <input name="prodSize" type="text" class="form-control" id="size" placeholder="M" [(ngModel)]="prodData.prodSize">
      </div>
      <button type="submit" class="btn btn-default">Submit</button>
    </form>

    <table class="table table-hover">
        <tr>
            <th>Product Name</th>
            <th>Product Price</th>
            <th>Product Size</th>
            <th> </th>
        </tr>
            <tr *ngFor="let prod of data">
                <td>{{ prod.prodName }}</td>
                <td>{{ prod.prodPrice }}</td>
                <td>{{ prod.prodSize }}</td>
                <td>
                    <input type="button" class="btn btn-danger" routerLink="/reload" (click) = "delFunc(prod._id)" class="del-btn"  value="Delete">
                </td>
            </tr>
    </table>

</div>

app.module.ts en cas de besoin: -

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { HttpModule } from '@angular/http';
import { FormsModule } from '@angular/forms';
import { RouterModule, Routes } from '@angular/router';

import { AllService } from './all.service';
import {AuthGuardService} from './auth-guard.service';
import {AuthenticationService} from './authentication.service';
import { ProductManageService } from './product-manage.service';

import { AppComponent } from './app.component';
import { FrontComponent } from './front/front.component';
import { ContentComponent } from './content/content.component';
import { ProductDetailComponent } from './product-detail/product-detail.component';
import { RegisterComponent } from './register/register.component';
import { LoginComponent } from './login/login.component';
import { ProfileComponent } from './profile/profile.component';
import { ManageProductComponent } from './manage-product/manage-product.component';

const routes = [
  {
    path: '',
    component: ContentComponent
  },
  {
    path: 'product',
    component: ProductDetailComponent
  },
  { 
    path: 'login',
     component: LoginComponent 
  },
  {
   path: 'register',
    component: RegisterComponent
  },
  {
   path: 'profile',
   component: ProfileComponent,
   canActivate: [AuthGuardService] 
  },
  {
    path: 'manage',
    component: ManageProductComponent,
  },
  { path: 'reload',
    redirectTo: 'manage',
    pathMatch: 'full'
  },
];

@NgModule({
  declarations: [
    AppComponent,
    FrontComponent,
    ContentComponent,
    ProductDetailComponent,
    RegisterComponent,
    LoginComponent,
    ProfileComponent,
    ManageProductComponent
  ],
  imports: [

    BrowserModule,
    FormsModule,
    HttpClientModule,
    HttpModule,
    RouterModule.forRoot(routes, {
      onSameUrlNavigation: 'reload'
    }),
  ],
  providers: [
    AllService,
    AuthenticationService, 
    AuthGuardService,
    ProductManageService
  ],
  bootstrap: [AppComponent],
  exports: [RouterModule]
})
export class AppModule { }
4
Coder

Cause

Votre table n'est pas mise à jour car le modèle (data) n'a pas été mis à jour après l'appel de l'API. Il existe plusieurs façons de mettre à jour le modèle, et je recommande les options 3 ou 2 dans cette réponse.

Option 1

Comme certains l'ont déjà dit, la première façon consiste à supprimer l'élément du tableau dans le modèle de vue:

delFunc(id){
    this.add.deleteProd(id);
    this.data = this.data.filter(item => item.id != id);
}

L'inconvénient de cette approche est que même si l'élément a été supprimé dans le frontend, comment pouvez-vous être sûr qu'il a bien été supprimé de la base de données dans le backend? Signification, l'élément serait supprimé de votre table HTML frontend même si this.add.deleteProd(id) ne fonctionne pas correctement et que l'objet n'a pas été réellement supprimé dans le backend. Par conséquent, vous ne pouvez pas être sûr que la vue frontend représente fidèlement la réalité du backend.

Option 2

La deuxième façon consiste à "recharger" la table en interrogeant à nouveau le backend. Cela prend le "moins de travail" car tout ce que vous avez à faire est d'appeler simplement la fonction pour charger à nouveau les données:

delFunc(id) {
    this.add.deleteProd(id)
    .subscribe(()=> {
        this.fetchData();
    });
}

ngOnInit() {
    this.fetchData();
}

fetchData() {
    this.allService.getAlldata().subscribe(data =>{
        this.data = data;
    });
}

Ici, vous gagnez la "précision" de la réalité mais sacrifiez les performances lorsque vous effectuez deux REST appels chaque fois que vous supprimez.

Option 3

La troisième façon prend "le plus de travail", mais fournit un compromis entre la précision de la réalité et les performances. Fondamentalement, vous devrez réécrire le backend de telle sorte qu'après avoir supprimé la base de données, le backend REST/La méthode API renvoie le nouvel ensemble de données qui se trouve maintenant dans la base de données.

Ensuite, vous pouvez faire quelque chose comme ça dans votre composant Angular:

delFunc(id) {
    this.add.deleteProd(id)
    .subscribe(newData => {
        this.data = newData;
    });
}

Cela suppose que vous avez le contrôle sur le code principal. Vous devrez peut-être faire this.data = newData.json(); à la place, selon ce que la méthode this.add.deleteProd(id) renvoie.

Choisissez l'option qui convient le mieux à votre situation. Faites-moi savoir si cela fonctionne pour vous.

15
jamesngyz

Pas besoin de recharger la page, passez simplement l'index du côté du modèle et supprimez ces données de l'index en cas de suppression réussie.

Côté modèle

<tr *ngFor="let prod of data;let i = index">
    ....
    <input type="button" class="btn btn-danger" (click) = "delFunc(prod._id,i)" class="del-btn"  value="Delete">
    ....
</tr>

Côté composant:

delFunc(id , index){
    // console.log("Delete ",id);
    this.add.deleteProd(id).subscribe(()=>{
        this.data.splice(index, 1);
    });
}
2
Vivek Doshi

Modifiez votre événement de clic pour passer dans tout l'objet:

<input type="button" class="btn btn-danger" routerLink="/reload" (click) = "delFunc(prod)" class="del-btn"  value="Delete">

Et votre delFunc comme:

delFunc(prod){
    this.data.splice(this.data.indexOf(prod), 1);
    this.add.deleteProd(prod._id);
}
1
Jan Wendland

Vous n'avez pas besoin de naviguer, vous devez supprimer le produit supprimé de vos données qui est utilisé pour créer votre modèle.

  delFunc(id){
    // console.log("Delete ",id);
    this.add.deleteProd(id);
    const item = this.data.find(item => item.id === id);
    this.data.splice(this.data.indexOf(item)));
  }

Vous pouvez bien sûr simplement déclencher le rechargement de vos données et appeler à nouveau votre back-end, qui serait sous-optimal.

1
alsami

Vous pouvez supprimer le produit sur this.data via l'index.

Modifiez votre code pour cela:

HTML ....

<tr *ngFor="let prod of data; let i = index;">

....

<input type="button" class="btn btn-danger" routerLink="/reload"
 (click) = "delFunc(prod._id, i)" class="del-btn"  value="Delete">

. ts

 delFunc(id, index){
        // console.log("Delete ",id);
        this.add.deleteProd(id, index);
        this.data(index, 1);
         //this.router.navigateByUrl("/reload");   }
0
ceurif