我有一个简单的动作,我想在我的状态下添加一些对象到一个数组中。不知何故,它运行到一个死循环。我还不知道为什么会发生这种情况。我是ngrx和Angular的新手。我做错了什么?这个动作是在单击按钮后触发的,它调用了shelf-item.component.ts
中的以下函数onAddToCartButtonClicked()
这是我在reducer.ts
中的减速器:
export type ShoppinCartState = {
CartIsOpen: boolean;
Entries: ShoppingCartEntry[];
};
export function shoppingCartReducer(
state: ShoppinCartState = { CartIsOpen: false, Entries: [] },
action: ShoppingCartAction
) {
switch (action.type) {
case "CART_TOGGLE":
return {
...state,
CartIsOpen: !state.CartIsOpen
};
case "CART_CLOSE":
return {
...state,
CartIsOpen: false
};
case "CART_ADD_ENTRY":
return {
...state,
Entries: [...state.Entries.concat(action.payload)]
};
default:
return state;
}
}
这基本上就是我的shelf-item-component.ts
export class ShelfItemComponent implements OnInit {
@Input() product: Product;
selectedOption: ProductVariant;
isInputMissing: boolean = false;
constructor(private store: Store<State>) {}
ngOnInit() {
if (this.product && this.product.variations) {
if (this.product.variations.length === 1) {
this.selectedOption = this.product.variations[0];
}
}
}
onAddToCartButtonClicked() {
if (this.isValid()) {
this.addProductToCart();
}
}
addProductToCart() {
this.store.dispatch({ type: "SET_LOADING" });
this.store
.select(state => state.shoppingCartReducer.Entries)
.subscribe(data => this.dispatchNewCartEntry(data));
}
dispatchNewCartEntry(entries: ShoppingCartEntry[]) {
this.store.dispatch(
new AddShoppingCartEntry(this.constructNewCartEntry(entries))
);
this.store.dispatch({ type: "UNSET_LOADING" });
}
constructNewCartEntry(entries: ShoppingCartEntry[]): ShoppingCartEntry {
let matchingEntry = entries.find(
entry =>
entry.product.id === this.product.id &&
entry.variation === this.selectedOption
);
let amount = matchingEntry ? matchingEntry.amount + 1 : 1;
return {
product: this.product,
amount: amount,
variation: this.selectedOption
};
}
isValid(): boolean {
if (this.isOptionToBeSelected()) {
if (this.selectedOption) {
this.isInputMissing = false;
return true;
} else {
this.isInputMissing = true;
return false;
}
}
return true;
}
isOptionToBeSelected(): boolean {
if (this.product && this.product.variations.length > 0) {
return true;
} else {
return false;
}
}
onOptionSelected(option: ProductVariant) {
this.selectedOption = option;
this.isInputMissing = false;
}
}
那是我的shelf-item-component.html
<h3>{{ product.title }}</h3>
<img *ngIf="!product.image" src="../../../assets/img/esansBottles Kopie.png" />
<div
[ngClass]="{ inValid: isInputMissing }"
*ngIf="product.variations.length > 1"
>
<form>
<div class="variation" *ngFor="let variation of product.variations">
<label>
<input
type="radio"
name="variation"
value="variation"
(change)="onOptionSelected(variation)"
/>
{{ variation.option }} {{ variation.price }} €</label
>
</div>
</form>
</div>
<div *ngIf="product.variations.length === 1">
<div *ngIf="selectedOption">
{{ selectedOption.option }} {{ selectedOption.price }}€
</div>
</div>
<div>
<p>{{ product.description }}</p>
</div>
<div (click)="onAddToCartButtonClicked()" class="addToCartButton">
In den Warenkorb
</div>
这是父组件shelf.component.html,在其中创建了有问题的组件:
<div class="container">
<div *ngFor="let product of products | async">
<app-shelf-item [product]="product"></app-shelf-item>
</div>
</div>
它是shelf.component.ts file
:
export class ShelfComponent implements OnInit {
@Input() products: Observable<Product[]>;
constructor(private store: Store<State>) {}
ngOnInit() {}
}
我真的卡住了,不明白:/
3条答案
按热度按时间nnsrf1az1#
正如Fateh提到的,它将被触发,并且值将被订阅。如果这个操作在订阅存储选择器时被触发一次,您可以将上面的语句链接到RxJS take()操作符。
该操作符将确保只有提供给take()操作符的指定计数值才会由源观察对象发出。
cs7cruho2#
这是正常的,您在此处订阅购物车实体
这意味着每次购物车条目更改时,将在订阅内触发调度
n9vozmp43#
我也遇到过类似的问题--完全是我的错--减速器和效果都在无限循环中。花了几个小时调试,才发现我在复制粘贴cident中复制了动作名称(令人作呕〉.〈)