我有一个组件:
import { Component, OnInit, Input, NgZone, ChangeDetectorRef } from '@angular/core';
import { Product } from '../product'; // data types
import { PRODUCTS } from '../mock-products'; // database
import { CartService } from '../cart.service'; // service
import { Subscription } from 'rxjs/Subscription';
@Component({
selector: 'app-checkout',
templateUrl: './checkout.component.html',
styleUrls: ['./checkout.component.css']
})
export class CheckoutComponent implements OnInit {
get shoppingCart(): Product[] {
const result = this.cartService.get();
return result;
}
cartTotal: number;
@Input() PRODUCTS: Product;
constructor(private cartService: CartService, private zone: NgZone,
private changeDetectionRef: ChangeDetectorRef) {
this.cartService.shoppingCart.subscribe((nextValue) => {
this.changeDetectionRef.detectChanges();
console.log('nextValue', nextValue); // returns properly
console.log(`subscribe: ${NgZone.isInAngularZone()}`); // RETURNS TRUE
});
}
ngOnInit() {
console.log(`ngOnInit: ${NgZone.isInAngularZone()}`); // RETURNS TRUE
this.estimatedTotal(); // THIS FUNCTION RUNS BUT IS NEVER UPDATED WITH NEW VALUES
}
deleteItem(id, shoppingCart) {
console.log('id to be deleted ' + id.toString());
const newCart = [];
for (let i = 0; i < shoppingCart.length; i++) {
if (shoppingCart[i].id !== id) {
newCart.push(shoppingCart[i]);
}
}
this.cartService.set(newCart);
this.changeDetectionRef.detectChanges(); // THIS DOES NOT SEEM TO BE WORKING AT ALL
}
estimatedTotal() {
const totals = [];
for (let i = 0; i < this.shoppingCart.length; i++) { // looping through cart
if (this.shoppingCart != null && this.shoppingCart.length > 0) {
totals.push(this.shoppingCart[i].price * this.shoppingCart[i].quantity);
this.cartTotal = totals.reduce((total, amount) => total + amount);
} else {
this.cartTotal = 0;
}
}
}
它利用服务来获取()和设置()项目到本地存储:
import { Injectable, NgZone } from '@angular/core';
import { Product } from './product'; // data model
import { PRODUCTS } from './mock-products'; // database +
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { ReplaySubject } from 'rxjs/ReplaySubject';
import { Subject } from 'rxjs/Subject';
import { CartItemComponent } from './cart-item/cart-item.component';
import { CheckoutComponent } from './checkout/checkout.component';
@Injectable()
export class CartService {
shoppingCart: Subject<Object> = new ReplaySubject<Object>(1);
constructor() { console.log(`cartService: ${NgZone.isInAngularZone()}`); }
set(shoppingCart: Product[]) {
this.shoppingCart.next(shoppingCart);
localStorage.setItem('shoppingCart', JSON.stringify(shoppingCart));
}
get() {
return JSON.parse(localStorage.getItem('shoppingCart'));
}
}
这是HTML:
<div class="pinned">
<button (click)="checkOut()">
<img src="./assets/icons/shoppingcart.png"/>
</button>
</div>
<!--Modal 3-->
<div id="shoppingCart" class="modal">
<!--Modal 3 Content-->
<div class="modal-content">
<span class="closeModal" (click)="close()">×</span>
<h3> Shopping Cart </h3>
<table id="shoppingCartTable">
<thead>
<th> Item </th>
<th> </th>
<th> </th>
<th> Price </th>
<th> Quantity </th>
<th> Total </th>
<th> Delete? </th>
<tr *ngFor="let cartItem of this.shoppingCart">
<td>{{cartItem.productName}}</td>
<td><img src={{cartItem.img}} /></td>
<td>{{cartItem.description}}</td>
<td>${{cartItem.price}}</td>
<td>{{cartItem.quantity}}</td>
<td>${{cartItem.price * cartItem.quantity}}</td>
<td><button><img src="./assets/icons/trashcan.png" (click)="deleteItem(cartItem.id, shoppingCart)" /></button></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td>Estimated Total:</td>
<td></td>
<td style = "font-weight:bold">${{cartTotal}}</td>
<td></td>
</tr>
<tr>
<button id="checkoutBtn" (click)="confirmCheckout()"> Checkout
</button>
</tr>
</thead>
<tbody id="tbodyCart"></tbody>
</table>
</div>
</div>
我遇到的问题是,当添加、删除新项目或以任何方式更改 localStorage(通过 cartService)时,我的 UI 没有更新 {{cartTotal}} 。我认为这可能是一个区域问题,也许在区域外处理了一些更改,并且 NgZone.isInAngularZone() 的所有实例都返回了true。我订阅了 cartService 以查看是否可以解决问题,然后启动 ChangeDetection,这也没有给我想要的结果。然后我尝试在订阅上手动强制执行 ChangeDetection ,这也不会更新我的{{cartTotal}}。我已经坚持了一天多,任何建议将不胜感激!