角度故障清空阵列



见鬼,我有一个电子商务应用程序,我试图在付款成功后清空购物车,无论我尝试了什么,数组都不会清空。我尝试过cartItems.length=0,cartItems=[]以及拼接。我一定是错过了什么。下面的代码片段我将带你浏览一遍。

这是我的型号

import { Product } from './product';

export class CartItem {
id: number;
productId: number;
productName: string;
qty: number;
price: number;
size:string;
imageUrl:string;
constructor(id:number, size:string,  
product:Product, qty= 1) {
this.id = id;
this.productId = product.id;
this.price = product.price;
this.size = size;
this.productName = product.name;
this.qty = qty;
this.imageUrl = product.imageUrl;        

}

}

这是我的汽车服务,你可以看到我删除并添加到购物车以及获取购物车项目,这里没有问题。删除和添加是html 上的按钮点击

export class CartService {

product: any;

cartItem: CartItem[] = [];

cartUrl = 'http://localhost:4000/cart';

constructor(private http: HttpClient, private router: Router, 
private route: ActivatedRoute) {

}
getCartItems(): Observable<CartItem[]> {
return this.http.get<CartItem[]>(cartUrl).pipe(
map((result: any[]) => {
let cartItems: CartItem[] =[];

for(let item of result) {

cartItems.push( new CartItem(item.id, item.size, 
item.product, item.imageUrl ));

}

return cartItems;

})
);

}


addProductToCart(product:Product):Observable<any>{
return this.http.post(cartUrl, {product});
}

RemoveProductFromCart(id:number):Observable<void>{
//this.cartItems.splice(index,1)
alert("show deleted item");
return this.http.delete<CartItem[]>(`${this.cartUrl}/${id}`)
.pipe(catchError(_err => of (null))

);
}

buttonClick() { 
const currentUrl = this.router.url;
this.router.navigateByUrl('/', {skipLocationChange: 
true}).then(() => {
this.router.navigate([currentUrl]);
});

//alert("Should Reload");
} 

addPurseToCart(product:Product):Observable<any>{
return this.http.post(cartUrl, {product})

}

}

这是checkout组件,我注入了cart组件,这样我就可以调用cart组件中的空cart函数。我确实导入了CartComponent。结账基于购物车。当购物车清空时,应该结账

@Component({

providers:[CartComponent],   //injected CartComponent
selector: 'app-checkout',
templateUrl: './checkout.component.html',
styleUrls: ['./checkout.component.scss']
})

export class CheckoutComponent implements OnInit {

// @ViewChild(CartComponent)   // @ViewChild(CartItemComponent) cartitemComponent: CartItemComponent
cartComponent: CartComponent

@Input() product: CartItem;
@Input() cartItem: CartItem;


cartUrl = 'http://localhost:4000/cart';
size;
cartItems = [];
cartTotal = 0;
itemTotal = 0;  
shipping = 8.00;
estimatedTax = 0;
myValue: any;


constructor(private msg: MessengerService, private route: 
ActivatedRoute,
private router: Router,  private 
cartService:CartService, 
private productService: ProductService, private 
comp:CartComponent) {}

ngOnInit() {

this.loadCartItems();
}



}
loadCartItems(){
this.cartService.getCartItems().subscribe((items: 
CartItem[]) => {
this.cartItems = items;
this.calcCartTotal();
this.calNumberOfItems();
})
}
calcCartTotal() {

this.cartTotal = 0;
this.cartItems.forEach(item => {
this.cartTotal += (item.qty * item.price); 

})
this.cartTotal +=  this.shipping;
this.myValue = this.cartTotal
render(
{
id:"#paypal-button-container",
currency: "USD",
value: this.myValue,
onApprove: (details) =>{
alert("Transaction Suceessfull")
console.log(this.myValue);
this.comp.handleEmptyCart();


}


} 
);
}


calNumberOfItems(){
console.log("Trying to get tolal items")
this.itemTotal = 0;
this.cartItems.forEach(item => {
this.itemTotal += item.qty;
})

}

}

推车组件

export class CartComponent implements OnInit {


@Input() product: CartItem;
@Input() cartItem: CartItem;

//items: CartItem [] =[];

cartUrl = 'http://localhost:4000/cart';

val;
size;
cartItems = [];




cartTotal = 0
itemTotal = 0

constructor(private msg: MessengerService, private 
cartService:CartService, private productService: 
ProductService, private formBuilder:FormBuilder, private 
_data:AppserviceService, private router:Router) { }




ngOnInit(): void {

this.handleSubscription();
this.loadCartItems();


}

handleSubscription(){

this.msg.getMsg().subscribe((product: Product) => {   
})

}


loadCartItems(){

this.cartService.getCartItems().subscribe((items: 
CartItem[]) => {
this.cartItems = items;
console.log("what is in cartItems" + this.cartItems)
console.log("What does this property hold" + 
this.cartItem)
this.calcCartTotal();
this.calNumberOfItems();
})
}



calcCartTotal() {
this.cartTotal = 0
this.cartItems.forEach(item => {
this.cartTotal += (item.qty * item.price)  
})

}

calNumberOfItems(){
console.log("Trying to get tolal items")
this.itemTotal = 0
this.cartItems.forEach(item => {
this.itemTotal += item.qty
})

}

handleEmptyCart(){

alert("Hit Empty Cart");

/*here I get the cart items to see what is in the array 
and try to empty, it does show tow objects in the 
array*/
this.cartService.getCartItems().subscribe((items: 
CartItem[]) => {
this.cartItems = items;
this.cartItems.length=0
// this.cartItems = [];
console.log("what is in cartItems"  + this.cartItems)


})


}



}

我用了不同的方法试图清空购物车,但什么都不起作用。这让我觉得我踩到了什么东西,或者以某种方式创建了调用loadCartItems的事件,很多时候都不确定,但根据我的研究,其中一种方法应该有效。如果有人能帮我,我就陷入困境了。我将不胜感激。

简短回答:运行更改检测ChangeDetectorRef.detectChanges()

长答案:您需要了解角度是如何工作的。让我们假设一个简单的例子:

<div id="val">{{val}}</div><button (click)="val++">Increase<div>

所以,当你点击按钮时,变量会发生变化,但谁会改变实际的#valdiv内容?答案是Angular使用zone.js来修补/更改许多函数,以便在大多数js事件之后运行Angular更改检测(您可以控制这些事件的类型以包括/排除其中一些(。同样Promise也是以同样的方式修补的,这就是为什么在一些Promise是解析更改检测后运行的原因。

然而,在这里,您运行了一些带有onApprove回调的render方法,它可能是某个第三方库(?(,而zone.js对此一无所知(https://angular.io/guide/zone#ngzone-奔跑和奔跑(。虽然运行detectChanges可以帮助你,但你最好重写你的代码,所以onApprove总是在Angular区域,你将来使用这种方法时永远不会遇到类似的错误。

最新更新