如何在angular5中删除后刷新页面

问题描述 投票:2回答:5

我正在制作一个平均堆栈购​​物应用程序(Angular 5)。我制作了一个管理产品组件,其中包含所有产品的列表和删除按钮。删除按钮有效,但产品在表中列出,因为它已从数据库中删除。所以,我想知道是否有任何可能的方法在删除后重新渲染或刷新组件。我试图导航到同一页面,但它不会工作,因为角度不允许。请任何人都可以帮忙。我在stackoverflow上找不到任何具体的答案,所以我不得不问它。

我的manage-product.component.ts是: -

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);


}

}

我的管理组件的html文件是: -

    <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如果您需要: -

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 { }
angular mean-stack angular5
5个回答
9
投票

原因

您的表未更新,因为API调用后模型(data)未更新。有几种方法可以更新模型,我建议在此答案中使用选项3或2。

选项1

正如一些人已经说过的那样,第一种方法是从视图模型中的数组中删除元素:

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

这种方法的缺点是,即使项目已在前端删除,您如何确保它确实已成功从后端的数据库中删除?这意味着,即使this.add.deleteProd(id)无法正常工作且该对象实际上未在后端删除,该项也将从您的前端HTML表中删除。因此,您无法确定前端视图是否准确地表示后端的实际情况。

选项2

第二种方法是通过再次查询后端来“重新加载”表。这需要“最少工作”,因为您只需调用函数再次加载数据:

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

ngOnInit() {
    this.fetchData();
}

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

在这里,您获得了现实的“准确性”,但牺牲了性能,因为每次删除时都会进行两次REST调用。

选项3

第三种方式采用“大多数工作”,但在现实和性能的准确性之间提供折衷。基本上,您需要重新编写后端,以便在删除数据库后,后端REST / API方法返回现在在数据库中的新数据集。

然后,您可以在Angular组件中执行以下操作:

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

这假设您可以控制后端代码。您可能需要改为使用this.data = newData.json();,具体取决于this.add.deleteProd(id)方法返回的内容。

选择最适合您情况的选项。如果这对您有用,请告诉我。


0
投票

您无需导航,应从用于创建模板的数据中删除已删除的产品。

  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)));
  }

您当然可以触发您的数据重新加载并再次调用您的后端,这将是次优的。


0
投票

更改单击事件以传入整个对象:

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

你的delFunc就像:

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

0
投票

无需重新加载页面,只需从模板侧传递索引,并在删除成功时从索引中删除该数据。

模板面

<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>

组件方面:

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

0
投票

您可以通过索引删除this.data上的产品。

改变你的代码:

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");   }
© www.soinside.com 2019 - 2024. All rights reserved.