[英]remove item shopping cart angular
我只想在点击时删除一个项目,我制作了一个代码,但我有错误,我已经坚持了 2 天。
错误类型错误:this. addedBook.indexOf 不是函数
我已经在我们关闭的网站上问过这个问题,因为缺乏信息,但我很清楚准确
感谢您的帮助
服务
export class BookService {
url: string = 'http://henri-potier.xebia.fr/books';
public booktype: BookType[];
item: any = [];
constructor(private http: HttpClient) { }
getBookList(): Observable<BookType[]> {
return this.http.get<BookType[]>(this.url);
}
addToBook() {
this.item.push(this.booktype);
}
}
addToBook() 在这里添加书籍,但我不知道如何使用它在我的 ts 文件中显示添加的书籍
文件
export class PaymentComponent implements OnInit {
addedBook: any = [];
product:any;
constructor(private bookService: BookService) { }
ngOnInit(): void {
this.addedBook = this.bookService.getBookList();
}
delete() {
this.addedBook.splice(this.addedBook.indexOf(this.product), 1);
}
}
html
<div class="product" *ngFor="let book of addedBook | async">
<div class="product-image">
<img [src]="book.cover" alt="book">
</div>
<div class="product-details">
<div class="product-title">{{book.title}}</div>
</div>
<div class="product-price">{{book.price | currency: 'EUR'}}</div>
<div class="product-quantity">
<input type="number" value="1" min="1">
</div>
<div class="product-removal">
<button class="remove-product" (click)="delete()">
Supprimé
</button>
</div>
界面
export interface BookType {
title: string;
price: number;
cover: string;
synopsis: string;
}
我认为this.bookService.getBookList()
返回Observable
所以对于你来说它不是使用async
管道的最佳解决方案。 您应该简单地订阅您的服务器响应,而不是将其分配给您的变量。 删除项目后只重新渲染你的ngFor
。
JS
export class PaymentComponent implements OnInit {
addedBook: any[] = [];
product:any;
constructor(private bookService: BookService) { }
ngOnInit(): void {
// Observable
this.bookService.getBookList().subscribe(response =>{
this.addedBook = response;
});
// Promise
/*
this.bookService.getBookList().then(response=>{
this.addedBook = response;
})*/
}
delete(){
this.addedBook.splice(this.addedBook.indexOf(this.product), 1);
// rerender your array
this.addedBook = [...this.addedBook];
}
}
HTML
<div class="product" *ngFor="let book of addedBook">
<div class="product-image">
<img [src]="book.cover" alt="book">
</div>
<div class="product-details">
<div class="product-title">{{book.title}}</div>
</div>
<div class="product-price">{{book.price | currency: 'EUR'}}</div>
<div class="product-quantity">
<input type="number" value="1" min="1">
</div>
<div class="product-removal">
<button class="remove-product" (click)="delete()">
Supprimé
</button>
</div>
我会建议这样的
服务文件
export class BookService {
url: string = 'http://henri-potier.xebia.fr/books';
//add an observable here
private bookUpdated = new Subject<bookType>();
public booktype: BookType[] = [];//initializa empty array
item: any = [];
constructor(private http: HttpClient) { }
//Ive changet the get method like this
getBookList(){
this.http.get<bookType>(url).subscribe((response) =>{
this.bookType.push(response);//Here you add the server response into the array
//here you can console log to check eg: console.log(this.bookType);
//next you need to use the spread operator
this.bookUpdated.next([...this.bookType]);
});
}
bookUpdateListener() {
return this.bookUpdated.asObservable();//You can subscribe to this in you TS file
}
}
现在在您的 TS 文件中,您应该订阅更新侦听器。 这通常在 NgOnInit 中完成
像这样的东西:
export class PaymentComponent implements OnInit {
addedBook: BookType;
product:any;
constructor(private bookService: BookService) { }
ngOnInit(): void {
this.bookService.bookUpdateListener().subscribe((response)=>{
this.addedBook = response;//this will happen every time the service class
//updates the book
});
//Here you can call the get book method
this.bookService.getBookList();
}
delete() {
this.addedBook.splice(this.addedBook.indexOf(this.product), 1);
}
}
本质上,当书籍更改或更新时,您会订阅。 现在您可以简单地在 HTML 中使用 addedBook.title 或任何您想要的内容。
更新
我构建了一个特殊的 stackblitz,因此您可以在此处查看它的运行情况,这是链接;
你不能在Observable
流上使用 javascript splice
,它不是一个Array
。
为了能够从流中删除项目,您需要将它(流)与另一个流(在您的情况下)要删除的项目的 ID 结合起来。
所以首先创建2个流
// the $ sign at the end of the variable name is just an indication that this variable is an observable stream
bookList$: Observable<any[]>; // holds bookList stream
deleteBook$ = new Subject<{ id: string }>(); // holds book id stream
现在将从您的数据库(这是一个可观察的流)获得的结果传递给您刚刚创建的bookList$
流
ngOnInit(): void {
this.bookList$ = this.bookService.getBookList().pipe(
delay(0)
);
}
将您的html
模板更改为 .. 并通过管道从数据库中获取结果
<div class="product" *ngFor="let book of (bookList$ | sync)">
...
// make sure you include your`remove-product` button inside `*ngFor` loop so you can pass the `book id` you want to remove to the `delete()` function.
<button class="remove-product" (click)="delete(book)">
Supprimé
</button>
</div>
现在回到你的ts
文件,我们将通过修改数组从 STREAM 中删除项目并返回一个新的流。
bookList$: Observable<any[]>; // holds bookList stream
deleteBook$ = new Subject<{ id: string }>(); // holds book id stream
ngOnInit(): void {
this.bookList$ = this.this.bookService.getBookList().pipe(
delay(0)
);
combineLatest([
this.bookList$,
this.deleteBook$
]).pipe(
take1(),
map(([bookList, deleteBook]) => {
if (deleteBook) {
var index = bookList.findIndex((book: any) => book.id === deleteBook.id);
if (index >= 0) {
bookList.splice(index, 1);
}
return bookList;
}
else {
return bookList.concat(deleteBook);
}
})
).subscribe();
}
现在剩下要做的就是删除该项目
delete(book: any) {
this.deleteBook$.next({ id: book.id }); pass the book you want to remove to the stream, `combineLatest` will take care of the rest
}
如果您退出,请不要忘记我:) 祝您好运!
从您的代码中,我们可以看到getBookList()
返回一个 Observable。 由于addedBook
不是数组引用,因此不会有数组方法。 这就是你的问题的原因。
如果你想对服务数据做一些操作,订阅 observable 并将值的引用存储到addedBook
。
导出类 PaymentComponent 实现 OnInit {
...
ngOnInit(): void {
this.bookService.getBookList().subscribe(
res => { this.addedBook = res }
);
}
...
}
并且您需要从 html 中删除 async 关键字
Typescript 主要用于在编译时识别此类问题。 它不会在编译时抛出错误的原因是您已将addedBook
指定为 any。 在声明您将其声明为数组和 onInit 时,您将其更改为 observable,如果您已指定type[]
例如: string[]
,则可以避免这种情况
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.