繁体   English   中英

删除项目购物车角度

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM