仅在页面刷新后才刷新购物车上的元素数 Angular 8
Number of elements on cart refreshes only after page refresh Angular 8
我正在开发一个简单的购物 MEAN 堆栈应用程序。
在 header 组件上,我有一个带有徽章的购物车,显示用户购物车上的元素数量,当我单击添加到购物车按钮(位于我的产品组件上)时,产品正常添加但数量购物车上的元素仅在我刷新页面时更新。
这是我的 header 模板代码:
<div class="input-group input-group-sm">
<div class="input-group-append" *ngFor="let p of panier">
</div>
<a class="btn btn-success btn-sm ml-3" *ngIf="isConnected" routerLink="/panier">
<!-- <a class="btn btn-success btn-sm ml-3" *ngIf="!isConnected" routerLink="/"></a> -->
<i class="fa fa-shopping-cart"></i> Cart
<span class="badge badge-light">{{getSize()}}</span>
</a>
</div>
这是我的 header 组件代码:
import { Component, OnInit, Input } from '@angular/core';
import { AuthentificationService } from '../authentification.service';
import { ProduitsService } from '../produits.service';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
user;
isConnected = false;
private panier: [];
size=0;
constructor(private AuthService : AuthentificationService,
private produitsService: ProduitsService) { }
setSize(quantite){
this.size+=quantite;
}
getSize(){
console.log(this.panier.length);
return this.size;
}
ngOnInit() {
this.AuthService.getUser().subscribe(data =>{
this.AuthService.getUser().subscribe(data =>{
console.log(data);
this.user = data;
if ( this.user ){Â this.isConnected = true;}
else {Â this.isConnected = false;}
console.log("est connecté : " + this.isConnected );
this.produitsService.getproduitsPanier(this.user).subscribe(data => {
// console.log("received : " + JSON.stringify(data));
this.panier = data;
if (this.panier) //dans le cas où le panier n'est pas encore initialisé
this.size = this.panier.length;
console.log("produits : " + this.panier);
});
});
});
}
}
这是我的产品组件代码:
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { ProduitsService } from '../produits.service';
import { AuthentificationService } from '../authentification.service';
import { Observable } from 'rxjs';
import {HomeComponent} from '../home/home.component'
@Component({
selector: 'app-produits',
templateUrl: './produits.component.html',
styleUrls: ['./produits.component.css']
})
export class ProduitsComponent implements OnInit {
private produits: Object[] = new Array();
user;
isConnected = false;
produitAEnvoyer = {
"email":"",
"img" :"",
"nom" :"",
"marque" : "",
"prix" : "",
"quantite" :""
};
constructor(
private route: ActivatedRoute,
private produitsService: ProduitsService,
private AuthService : AuthentificationService,
private HomeComponent : HomeComponent) {
}
ajouterAuPanier(img, nom, marque, prix){
this.produitAEnvoyer.email = this.user;
this.produitAEnvoyer.img = img;
this.produitAEnvoyer.nom = nom;
this.produitAEnvoyer.marque = marque;
this.produitAEnvoyer.prix = prix;
console.log(this.produitAEnvoyer);
this.produitsService.ajouterAuPanier(this.produitAEnvoyer).subscribe(data => {
console.log(data);
})
}
updateQuantite(value){
this.produitAEnvoyer["quantite"] = value;
console.log("quantite :"+this.produitAEnvoyer.quantite);
}
ngOnInit() {
this.produitsService.getProduits().subscribe(produits =>{
this.produits = produits;
for (const p of this.produits) {
this.produits.sort();
console.log(JSON.stringify(p));
}
});
this.AuthService.getUser().subscribe(data =>{
console.log(data);
this.user = data;
if ( this.user ){Â this.isConnected = true;}
else {Â this.isConnected = false;}
console.log("est connecte : " + this.isConnected+" email :"+this.user);
});
}
}
编辑 1:
这也是我的产品模板:
<link href="//maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="//maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<!------ Include the above in your HEAD tag ---------->
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.8/css/all.css">
<div class="container">
<br> <b><h2 class="text-center"> Catalog of All Our Products ! </h2></b>
<hr>
<br><br>
<div class="card" >
<table class="table table-hover shopping-cart-wrap">
<thead class="text-muted">
<tr>
<th scope="col">Product</th>
<th scope="col" width="120">Brand</th>
<th scope="col" width="120">Price</th>
<th scope="col" width="120">Quantity</th>
<th scope="col" width="200" class="text-right">Action</th>
</tr>
</thead>
<tbody *ngFor="let produit of produits">
<tr>
<td>
<figure class="media" >
<div class="img-wrap"><img src={{produit.img}} class="img-thumbnail img-sm"></div>
<figcaption class="media-body">
<h6 class="title text-truncate"> {{produit.nom}} </h6>
</figcaption>
</figure>
<td>
<div class="price-wrap">
<var class="price"> {{produit.marque}} </var>
</div> <!-- brand-wrap .// -->
</td>
<td>
<div class="price-wrap">
<var class="price">USD {{produit.prix}} $</var>
<small class="text-muted">(For 1 quantity)</small>
</div> <!-- price-wrap .// -->
</td>
<td>
<div class="price-wrap">
<input class="form-control" type="number" required (click)="updateQuantite($event.target.value)" min="1" max="20"/>
</div> <!-- quantity-wrap .// -->
</td>
<td class="text-right" >
<a title="" (click)= "ajouterAuPanier(produit.img, produit.nom, produit.marque, produit.prix)" class="btn btn-outline-success" data-toggle="tooltip" data-original-title="Save to Wishlist" > <i class="fa fa-heart" ></i> Add to cart</a>
</td>
</tr>
<tr>
</tbody>
</table>
</div> <!-- card.// -->
</div>
<!--container end.//-->
您可以使用 @Input()
、@Output()
和 EventEmitter
设置父子组件之间的通信,但是由于您已经有了 ProduitService
,您可以使用它来共享数据。在您的情况下,项目总数。
在您的 ProduitService 中设置 BehaviorSubject
:
total = new BehaviorSubject<number>(0);
setTotalItems(value: number) {
this.total.next(value);
}
然后在您的 ProduitsComponent 中您可以设置值:
this.produitService.setTotalItems(value);
有关有点相关的案例,请参见:
它与我制作的 Stackblitz 相关:https://stackblitz.com/edit/angular-bqxex9
您可以找到使用共享服务在组件之间进行通信的简单实现。
使用Service
和Rxjs subject
可以解决您的问题。
当 add
或 remove
按钮被点击时,header 必须被通知某些事件发生并更新最新值。为此 Service
可以用作通信通道。
注意:@input
和@output
只有在组件处于parent-child关系时才能使用。所以对于这种情况,使用服务是最好的选择。
要更新 header 组件中的值,可以使用 Observable
。
header.component.ts
export class HeaderComponent {
...
ngOnInit() {
this.appService.getCount().subscribe(count => {
this.totalItem = count
}
);
}
...
}
应用服务
export class AppService {
count = 0;
simpleObservable = new Subject();
simpleObservable$ = this.simpleObservable.asObservable();
constructor() { }
addCount() {
this.count+=1;
this.simpleObservable.next(this.count)
}
removeCount() {
if (this.count > 0) { this.count-=1 };
this.simpleObservable.next(this.count)
}
getCount(){
return this.simpleObservable$;
}
}
我正在开发一个简单的购物 MEAN 堆栈应用程序。 在 header 组件上,我有一个带有徽章的购物车,显示用户购物车上的元素数量,当我单击添加到购物车按钮(位于我的产品组件上)时,产品正常添加但数量购物车上的元素仅在我刷新页面时更新。 这是我的 header 模板代码:
<div class="input-group input-group-sm">
<div class="input-group-append" *ngFor="let p of panier">
</div>
<a class="btn btn-success btn-sm ml-3" *ngIf="isConnected" routerLink="/panier">
<!-- <a class="btn btn-success btn-sm ml-3" *ngIf="!isConnected" routerLink="/"></a> -->
<i class="fa fa-shopping-cart"></i> Cart
<span class="badge badge-light">{{getSize()}}</span>
</a>
</div>
这是我的 header 组件代码:
import { Component, OnInit, Input } from '@angular/core';
import { AuthentificationService } from '../authentification.service';
import { ProduitsService } from '../produits.service';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
user;
isConnected = false;
private panier: [];
size=0;
constructor(private AuthService : AuthentificationService,
private produitsService: ProduitsService) { }
setSize(quantite){
this.size+=quantite;
}
getSize(){
console.log(this.panier.length);
return this.size;
}
ngOnInit() {
this.AuthService.getUser().subscribe(data =>{
this.AuthService.getUser().subscribe(data =>{
console.log(data);
this.user = data;
if ( this.user ){Â this.isConnected = true;}
else {Â this.isConnected = false;}
console.log("est connecté : " + this.isConnected );
this.produitsService.getproduitsPanier(this.user).subscribe(data => {
// console.log("received : " + JSON.stringify(data));
this.panier = data;
if (this.panier) //dans le cas où le panier n'est pas encore initialisé
this.size = this.panier.length;
console.log("produits : " + this.panier);
});
});
});
}
}
这是我的产品组件代码:
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { ProduitsService } from '../produits.service';
import { AuthentificationService } from '../authentification.service';
import { Observable } from 'rxjs';
import {HomeComponent} from '../home/home.component'
@Component({
selector: 'app-produits',
templateUrl: './produits.component.html',
styleUrls: ['./produits.component.css']
})
export class ProduitsComponent implements OnInit {
private produits: Object[] = new Array();
user;
isConnected = false;
produitAEnvoyer = {
"email":"",
"img" :"",
"nom" :"",
"marque" : "",
"prix" : "",
"quantite" :""
};
constructor(
private route: ActivatedRoute,
private produitsService: ProduitsService,
private AuthService : AuthentificationService,
private HomeComponent : HomeComponent) {
}
ajouterAuPanier(img, nom, marque, prix){
this.produitAEnvoyer.email = this.user;
this.produitAEnvoyer.img = img;
this.produitAEnvoyer.nom = nom;
this.produitAEnvoyer.marque = marque;
this.produitAEnvoyer.prix = prix;
console.log(this.produitAEnvoyer);
this.produitsService.ajouterAuPanier(this.produitAEnvoyer).subscribe(data => {
console.log(data);
})
}
updateQuantite(value){
this.produitAEnvoyer["quantite"] = value;
console.log("quantite :"+this.produitAEnvoyer.quantite);
}
ngOnInit() {
this.produitsService.getProduits().subscribe(produits =>{
this.produits = produits;
for (const p of this.produits) {
this.produits.sort();
console.log(JSON.stringify(p));
}
});
this.AuthService.getUser().subscribe(data =>{
console.log(data);
this.user = data;
if ( this.user ){Â this.isConnected = true;}
else {Â this.isConnected = false;}
console.log("est connecte : " + this.isConnected+" email :"+this.user);
});
}
}
编辑 1: 这也是我的产品模板:
<link href="//maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="//maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<!------ Include the above in your HEAD tag ---------->
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.8/css/all.css">
<div class="container">
<br> <b><h2 class="text-center"> Catalog of All Our Products ! </h2></b>
<hr>
<br><br>
<div class="card" >
<table class="table table-hover shopping-cart-wrap">
<thead class="text-muted">
<tr>
<th scope="col">Product</th>
<th scope="col" width="120">Brand</th>
<th scope="col" width="120">Price</th>
<th scope="col" width="120">Quantity</th>
<th scope="col" width="200" class="text-right">Action</th>
</tr>
</thead>
<tbody *ngFor="let produit of produits">
<tr>
<td>
<figure class="media" >
<div class="img-wrap"><img src={{produit.img}} class="img-thumbnail img-sm"></div>
<figcaption class="media-body">
<h6 class="title text-truncate"> {{produit.nom}} </h6>
</figcaption>
</figure>
<td>
<div class="price-wrap">
<var class="price"> {{produit.marque}} </var>
</div> <!-- brand-wrap .// -->
</td>
<td>
<div class="price-wrap">
<var class="price">USD {{produit.prix}} $</var>
<small class="text-muted">(For 1 quantity)</small>
</div> <!-- price-wrap .// -->
</td>
<td>
<div class="price-wrap">
<input class="form-control" type="number" required (click)="updateQuantite($event.target.value)" min="1" max="20"/>
</div> <!-- quantity-wrap .// -->
</td>
<td class="text-right" >
<a title="" (click)= "ajouterAuPanier(produit.img, produit.nom, produit.marque, produit.prix)" class="btn btn-outline-success" data-toggle="tooltip" data-original-title="Save to Wishlist" > <i class="fa fa-heart" ></i> Add to cart</a>
</td>
</tr>
<tr>
</tbody>
</table>
</div> <!-- card.// -->
</div>
<!--container end.//-->
您可以使用 @Input()
、@Output()
和 EventEmitter
设置父子组件之间的通信,但是由于您已经有了 ProduitService
,您可以使用它来共享数据。在您的情况下,项目总数。
在您的 ProduitService 中设置 BehaviorSubject
:
total = new BehaviorSubject<number>(0);
setTotalItems(value: number) {
this.total.next(value);
}
然后在您的 ProduitsComponent 中您可以设置值:
this.produitService.setTotalItems(value);
有关有点相关的案例,请参见:
它与我制作的 Stackblitz 相关:https://stackblitz.com/edit/angular-bqxex9
您可以找到使用共享服务在组件之间进行通信的简单实现。
使用Service
和Rxjs subject
可以解决您的问题。
当 add
或 remove
按钮被点击时,header 必须被通知某些事件发生并更新最新值。为此 Service
可以用作通信通道。
注意:@input
和@output
只有在组件处于parent-child关系时才能使用。所以对于这种情况,使用服务是最好的选择。
要更新 header 组件中的值,可以使用 Observable
。
header.component.ts
export class HeaderComponent {
...
ngOnInit() {
this.appService.getCount().subscribe(count => {
this.totalItem = count
}
);
}
...
}
应用服务
export class AppService {
count = 0;
simpleObservable = new Subject();
simpleObservable$ = this.simpleObservable.asObservable();
constructor() { }
addCount() {
this.count+=1;
this.simpleObservable.next(this.count)
}
removeCount() {
if (this.count > 0) { this.count-=1 };
this.simpleObservable.next(this.count)
}
getCount(){
return this.simpleObservable$;
}
}