我有一个CRUD页面,我希望在进行的每个操作中都可以对其进行更新。
因此,我尝试使用Observable,所有CRUD函数都可以正常工作(现在仅添加和删除),但是我需要刷新页面才能看到更改。
我尝试在每个操作函数的末尾调用this.ngOnInit()
函数,但没有任何效果。
productmanagement.component.ts
import { Component, OnInit } from '@angular/core';
import { routerTransition } from '../../../router.animations';
import { Observable } from 'rxjs';
import { Category } from 'src/app/_models';
import { CategoryService } from './_services/category.service';
@Component({
selector: 'app-productmanagement',
templateUrl: './productmanagement.component.html',
styleUrls: ['./productmanagement.component.scss'],
animations: [routerTransition()],
providers: [CategoryService]
})
export class ProductManagementComponent implements OnInit {
public categorysObservable$: Observable<Category>;
constructor(private categoryService: CategoryService) {}
ngOnInit() {
this.categorysObservable$ = this.categoryService.getAll();
}
categoryAdded(categoryname: string) {
this.categoryService.add(categoryname);
}
deleteCategory(category: any) {
this.categoryService.delete(category.idCategory);
}
}
category.service.ts
@Injectable()
export class CategoryService {
public categorysRequest: Observable<Category>;
public categorySubject: Subject<Category>;
constructor(private http: HttpClient) {
this.categorySubject = new ReplaySubject(1);
}
getAll(refresh: boolean = false) {
if (refresh || !this.categorysRequest) {
this.categorysRequest = this.http.get<Category>(`http://localhost:5000/api/Category`);
this.categorysRequest.subscribe(
result => this.categorySubject.next(result),
err => this.categorySubject.error(err)
);
}
return this.categorySubject.asObservable();
}
getById(id: number) {
return this.http.get(`http://localhost:5000/api/Category/` + id);
}
add(category: string) {
return this.http.post<Category>('http://localhost:5000/api/Category', {Category: category}).subscribe();
}
update(category: Category) {
return this.http.put(`http://localhost:5000/api/Category/` + category.idCategory, category);
}
delete(id: number) {
return this.http.delete<any>(`http://localhost:5000/api/Category?id=` + id).subscribe();
}
}
productmanagement.component.html
<!--Categorys-->
<div *ngIf="(categorysObservable$ | async)">
<div *ngFor="let category of (categorysObservable$ | async)">
<div class="card">
<div class="card-header">
<p style="display: inline" name='idCategory'> {{ category.category1 }} </p>
<button class='btn btn-danger' style="float: right;" (click)="deleteCategory(category)">delete</button>
<button class='btn btn-warning' style="float: right; margin-right: 10px;">edit</button>
<button class="btn btn-success" style="float: right; margin-right: 10px;">add Product</button>
</div>
<div *ngIf="category.product.length>0 else noProduct">
<table class="card-body table table-hover">
<thead>
<tr>
<th>Product</th>
<th>Reference</th>
<th>Serial Number</th>
<th>Price</th>
<th>quantity</th>
<th style="width: 165px"></th>
</tr>
</thead>
<tbody *ngFor="let prod of category.product">
<tr>
<td>{{ prod.product1 }}</td>
<td>{{ prod.reference }}</td>
<td>{{ prod.serialNumber }}</td>
<td>{{ prod.price }}</td>
<td>{{ prod.quantite }}</td>
<td>
<button class='btn btn-outline-warning'>edit</button>
<button class='btn btn-outline-danger'>delete</button>
</td>
</tr>
</tbody>
</table>
</div>
<ng-template #noProduct class="align-content-center">
<br>
<p class='text-center'>No Poducts yet</p>
</ng-template>
</div>
<br>
</div>
</div>
在组件中包含this.ngOnInit()
也无法在模板中使用AsyncPipe
。因此,我认为解决方案是通过将Observable与模板绑定。
答案 0 :(得分:1)
您太复杂了。如果“ http's” get()
本身将返回一个Observable,则无需创建另一个Observable。如果要取消订阅,可以在组件销毁时执行。如果我理解它是正确的,那么在if()
中添加getAll()
块的唯一目的就是不要调用另一个HTTP请求(如果已经在路上)。
将您的getAll()
设置为:
getAll() {
this.http.get<Category>(`http://localhost:5000/api/Category`);
}
在包含订阅的组件中创建一个类变量
getAllSubscription: Subscription
在组件中使用getAllCategories()
方法。
在课堂上不需要categorysObservable$
道具,而是制作一个categories
道具来保存实际数据。
getAllCategories() {
if (this.getAllSubscription) {
this.getAllSubscription.unsubscribe();
}
this.getAllSubscription = this.categoryService.getAll().subscribe((data) => {
this.categories = data;
}, (error) => {
// errors will come here
})
}
从模板中删除async
管道,并使用它
<div *ngIf="categories">
....
</div>
修改服务中的其他方法以仅返回一个Observable(不要在那里订阅),例如:
add(category: string) {
return this.http.post<Category>('http://localhost:5000/api/Category', {Category: category});
}
在您的getAllCategories()
和categoryAdded()
方法上调用deleteCategory()
categoryAdded(categoryname: string) {
this.categoryService.add(categoryname).subscribe((data) => {
// do something with data, show error success msgs,etc
this.getAllCategories();
})
}
注意:可能还有其他方法(使用rxjs
展平运算符)在update()和delete()Observables本身中实现getAll()
。我将它们用作单独的Observable,认为您需要从每个请求中获得单独的成功/错误响应。
更新
如果必须使用展平运算符,则可以通过这种方式实现。
add(category: string) {
return this.http.post<Category>('http://localhost:5000/api/Category', {Category: category}).pipe(
mergeMap((dataFromAdd) => {
// can just return this.getAll() if you don't care for the response of the above post() request. (But you should care!)
return this.getAll().pipe(
map((dataFromGetAll) => {
return {
addResponse: dataFromAdd,
allCategories: dataFromGetAll
}
})
)
})
)
}
在您的组件中,将categoryAdded()
修改为
categoryAdded(categoryname: string) {
this.categoryService.add(categoryname).subscribe((data) => {
this.categories = data.allCategories
})
}