2 回答

TA貢獻(xiàn)1884條經(jīng)驗(yàn) 獲得超4個(gè)贊
問題在于您的 if 語句的流程。在代碼的“onRemove”部分,您說的是“如果成分在列表中,則將其從列表中刪除。如果不在,則減少其數(shù)量?!?第二部分沒有任何意義,更重要的是,你永遠(yuǎn)也做不到,因?yàn)槌煞謶?yīng)該總是在列表中。
for (let eachIngredient of recipe.ingredients) {
let matched = this.groceryList.find(function(foundIngre) {
return foundIngre.name === eachIngredient.name;
});
if (
matched.name === eachIngredient.name &&
matched._id === eachIngredient._id
) {
let index = this.groceryList.findIndex(
(x) => x._id === matched._id
);
// Problem e ca eachIngredient.quantity se schimba
this.groceryList.splice(index, 1);
} else {
matched.quantity = matched.quantity - eachIngredient.quantity;
}
}
根據(jù)你所說的,你想要做的是:
減去歸因于已刪除配方的數(shù)量
如果新數(shù)量為零,則從列表中刪除該成分(盡管您也可以保留它并忽略數(shù)量為零的成分)
試試這個(gè):
for (let eachIngredient of recipe.ingredients) {
// I am assuming that ids are unique so I am not checking foundIngre.name at all,
// since I assume that ingredients with the same name must also have the same name
// I am also using findIndex first so that you don't need a second find when removing
const matchIndex = this.groceryList.findIndex(
(foundIngre) => foundIngre._id === eachIngredient._id
);
if ( matchIndex ) { // this should always be true
const matched = this.groceryList[matchIndex];
// preserve the entry if there is still some quantity
if ( matched.quantity > eachIngredient.quantity ) {
matched.quantity = matched.quantity - eachIngredient.quantity; // can use -= to shorten
}
// remove from the list only if there is no quantity remaining
else {
this.groceryList.splice(matchIndex, 1);
}
}
}
編輯: 嘗試更新和刪除數(shù)組中的項(xiàng)目是一種不必要的痛苦。修改后的代碼版本將 _groceryList 存儲在鍵控字典中。我最初打算按成分 ID 鍵,但在查看您的演示后,我發(fā)現(xiàn)我的假設(shè)是錯(cuò)誤的,即多個(gè)食譜中的相同成分將共享相同的 ID。所以我改為按成分名稱鍵入。這樣你就可以寫入 _groceryList[name] 并且它以前是否存在并不重要。
該類有一個(gè)公共的 getter groceryList,它將私有的 _groceryList 字典轉(zhuǎn)換為一個(gè)數(shù)組。
我還嘗試通過使用一個(gè)通用toggleIngredient函數(shù)來消除場景分支中不必要的代碼重復(fù),該函數(shù)使用布爾值checked來控制它是通過乘以加號還是減號來控制加法或減法。
import { Component } from "@angular/core";
import { Platform } from "@ionic/angular";
import { SplashScreen } from "@ionic-native/splash-screen/ngx";
import { StatusBar } from "@ionic-native/status-bar/ngx";
import { Subscription } from "rxjs";
export interface Ingredient {
_id: string;
name: string;
quantity: number;
}
export interface Recipe {
_id: string;
name: string;
ingredients: Ingredient[];
}
@Component({
selector: "app-root",
templateUrl: "app.component.html"
})
export class AppComponent {
private _recipesSub: Subscription;
constructor(
private platform: Platform,
private splashScreen: SplashScreen,
private statusBar: StatusBar,
) {
this.initializeApp();
}
initializeApp() {
this.platform.ready().then(() => {
this.statusBar.styleDefault();
this.splashScreen.hide();
});
}
private loadedRecipes: Recipe[] = [/*...*/]
// store the groceryList in a dictionary keyed by name
private _groceryList: Record<string, Ingredient> = {};
// getter returns the groceryList in array format, ignoring 0 quantities
get groceryList(): Ingredient[] {
return Object.values(this._groceryList).filter( ing => ing.quantity > 0 );
}
// get the current quantity for an ingredient by name, or 0 if not listed
currentQuantity( name: string ): number {
const ingredient = this._groceryList[name];
return ingredient ? ingredient.quantity : 0;
}
// update the quantity for an ingredient when checked or unchecked
// will add new ingredients, but never removes old ones
toggleIngredient( ingredient: Ingredient, checked: boolean ): void {
// add to or remove from quantity depending on the value of checked
const quantity = this.currentQuantity(ingredient.name) + (checked ? 1 : -1 ) * ingredient.quantity;
// replace the object in the grocery list dictionary
this._groceryList[ingredient.name] = {
...ingredient,
quantity
}
}
onCheckRecipe(e) { // you'll want to add a type for e here
for (let recipe of this.loadedRecipes) {
// find the matching recipe
if (recipe.name === e.detail.value) {
// loop through the recipe ingredients
for (let eachIngredient of recipe.ingredients) {
this.toggleIngredient(eachIngredient, e.detail.checked)
}
}
}
}
}

TA貢獻(xiàn)1898條經(jīng)驗(yàn) 獲得超8個(gè)贊
我認(rèn)為問題似乎出在代碼的這一部分
if (
matched.name === eachIngredient.name &&
matched._id === eachIngredient._id
) {
let index = this.groceryList.findIndex(
(x) => x._id === matched._id
);
// Problem e ca eachIngredient.quantity se schimba
this.groceryList.splice(index, 1);
} else {
matched.quantity = matched.quantity - eachIngredient.quantity;
}
if 語句應(yīng)該檢查數(shù)量而不是再次驗(yàn)證名稱和 id ,比如
if(matched.quantity <= eachIngredient.quantity){ // 拼接項(xiàng)目并刪除它。} else { // 減少數(shù)量 }
找到匹配成分的小建議。先用findIndex()檢索matchedIndex,再用grocerylist[matchedIndex]檢索item,避免再次遍歷grocerylist尋找索引進(jìn)行拼接。
添加回答
舉報(bào)