Angular 6复用带输入属性组件:product-quantity不显示求助
product-quantity Component in product-details Let's break down why your product-quantity component isn't showing up in product-details and fix it step by step:
1. The card-footer containing product-quantity isn't rendering at all
Looking at your product-details.component.ts, you haven't declared the showActions input property that your template uses in *ngIf="showActions && shoppingCart". Since showActions defaults to undefined, this condition evaluates to false, so the entire card-footer (and the product-quantity inside it) never gets rendered.
Fix: Add the showActions input to your product-details.component.ts:
export class ProductDetailsComponent implements OnInit { id; product$: Observable<Product>; cart$: Observable<ShoppingCart>; // Add this line to match the setup in product-card @Input('show-actions') showActions = true; constructor( private route: ActivatedRoute, private productService: ProductService, private cartService: ShoppingCartService, private categoryService: CategoryService ) { this.id = this.route.snapshot.params['id']; } async ngOnInit() { this.cart$ = await this.cartService.getCart(); this.product$ = await this.productService.get(this.id); } }
2. You're not properly accessing Observable data in the template
Your product$ and cart$ are Observables, but your template tries to use product and shoppingCart directly without subscribing to these streams. This means:
product.imageUrlwill beundefined(even if your API returns data)shoppingCartdoesn't exist as a variable, soshoppingCart.getQuantity(product)will failproduct-quantitywon't receive validproductorshopping-cartinputs
Fix: Use Angular's async pipe to subscribe to the Observables and extract the actual data in your template:
<div class="card"> <!-- Wrap product-related content in an async pipe block to get the product instance --> <div *ngIf="(product$ | async) as product"> <div *ngIf="product.imageUrl" [style.backgroundImage]="'url(' + product.imageUrl + ')'" class="card-img-top"> </div> <!-- Use async pipe to get the shopping cart instance, and combine with showActions --> <div *ngIf="showActions && (cart$ | async) as shoppingCart" class="card-footer"> <button *ngIf="shoppingCart.getQuantity(product) === 0; else updateQuantity" (click)="addToCart(product)" class="btn btn-secondary btn-block"> <i class="fa fa-cart-plus"></i>Add to Cart </button> <ng-template #updateQuantity> <!-- Now product and shoppingCart are valid instances to pass to product-quantity --> <product-quantity [product]="product" [shopping-cart]="shoppingCart"> </product-quantity> </ng-template> </div> </div> </div>
3. Missing addToCart method in product-details
Your template calls addToCart() on button click, but there's no corresponding method in product-details.component.ts. This would throw an error and could block template rendering.
Fix: Add the addToCart method (and update it to accept the product instance from the template):
export class ProductDetailsComponent implements OnInit { // ... existing code addToCart(product: Product) { this.cartService.addToCart(product); } }
Why these fixes work
- Adding
showActionsensures thecard-footercondition passes (by default) and renders the container forproduct-quantity. - The
asyncpipe properly subscribes to your Observables, giving you access to realProductandShoppingCartinstances. This letsshoppingCart.getQuantity(product)work correctly and passes valid inputs toproduct-quantity. - The
addToCartmethod lets the button function without errors, preventing any template rendering blocks.
内容的提问来源于stack exchange,提问作者Lebek

