Ошибка веб-компонента Lightning: ['set' на прокси: ловушка вернула ложное значение для свойства '0']
Я пытаюсь построить корзину, в которую я добавляю продукты, а затем могу их удалить. Однако при удалении я получаю сообщение об ошибке ['set' on proxy: trap returned falsish for property '0']
.
В своем компоненте ParentComponent
я выбираю продукты и добавляю их в массив cartItems
. Для каждого элемента корзины создается дочерний компонент cartRowItem
. Смотрите код ниже:
parentComponent.html:
<template>
<div class="slds-grid slds-gutters">
<lightning-card class="slds-col slds-size_1-of-3" title="Product Search">
<div class="slds-grid slds-gutters">
<div class="slds-col slds-size_2-of-3 slds-var-m-left_small">
<lightning-input type="text" placeholder="Search for a product" value={productSearchKey} onchange={handleSearchKeyChange}></lightning-input>
</div>
<div class="slds-col slds-size_1-of-3">
<button class="slds-button slds-button_brand slds-button_stretch slds-var-m-right_small" onclick={doSearch}>Search</button>
</div>
</div>
<template if:true={products}>
<lightning-datatable
key-field="id"
data={products}
columns={columns}
onrowaction={addToCart}
hide-checkbox-column>
</lightning-datatable>
</template>
</lightning-card>
<lightning-card class="slds-col slds-size_2-of-3" title="Product Cart">
<template for:each={cartItems} for:item="item">
<c-cart-row-item key={item.id} cart-item={item} cart-items={cartItems} oncartitemremove={handleRemove}></c-cart-row-item>
</template>
</lightning-card>
</div>
</template>
parentComponent.js:
import { LightningElement, api, track } from 'lwc';
import findProducts from '@salesforce/apex/TechDocSelfServeController.findProducts';
const tableColumns = [{
label: 'Product Code',
fieldName: 'ProductCode',
type: 'text',
sortable: true
},
{
label: 'Product Name',
fieldName: 'Name',
type: 'text',
sortable: 'true'
},
{
label: 'Add to Cart',
type: 'button-icon',
typeAttributes:
{
iconName: 'utility:add',
name: 'addToCart',
title: 'addToCart',
disabled: false,
alternativeText: 'Add to Cart',
}
}];
export default class TechDocSelfServe extends LightningElement {
products;
@api cartItems = [];
columns = tableColumns;
productSearchKey = '';
error;
doSearch() {
let productSearchKey = this.productSearchKey;
findProducts({ productSearchKey })
.then((result) => {
this.products = result;
this.error = undefined;
})
.catch((error) => {
this.error = error;
this.products = undefined;
});
}
addToCart(event) {
const row = event.detail.row;
this.cartItems = [...this.cartItems, row];
const selectedEvent = new CustomEvent("cartitemadd", {
detail: this.cartItems
});
console.log('cartItems on add -> ' + JSON.stringify(this.cartItems, null, 4));
this.dispatchEvent(selectedEvent);
}
handleSearchKeyChange(event) {
this.productSearchKey = event.target.value;
}
handleRemove(event) {
this.cartItems = event.detail
}
}
cartRowItem.html:
<template>
<template if:true={displayRow}>
<div class="slds-var-m-around_xx-small slds-box">
<lightning-card>
<div class="slds-text-heading_large slds-text-align_center "><u>{cartItem.Name}</u></div>
<lightning-button variant="destructive" label="Remove Item" title="RemoveItem" onclick={handleRemove} value={cartItem} class="slds-align_absolute-center"></lightning-button>
</lightning-card>
</div>
</template>
</template>
cartRowItem.js (обновлено в соответствии с комментарием Рахула):
import { LightningElement, api } from 'lwc';
export default class CartRowItem extends LightningElement {
@api cartItem;
_cartItems;
displayRow = true;
@api get cartItems() {
return this._cartItems;
}
set cartItems(value) {
this._cartItems = value;
}
handleRemove(event) {
console.log('Should remove here.')
var array = this._cartItems;
var key = event.target.value.Id;
var index = array.findIndex(function(item, i) {
return item.Id === key
});
array.splice(index, 1);
this._cartItems = array;
console.log('cartItems after remove -> ' + JSON.stringify(this._cartItems, null, 4));
const selectedEvent = new CustomEvent("cartitemremove", {
detail: this._cartItems
});
this.dispatchEvent(selectedEvent);
this.displayRow = false;
}
}
При нажатии кнопки «Удалить» в cartRowItem я получаю сообщение об ошибке ['set' on proxy: trap returned falsish for property '0']
с изменением номера в конце в зависимости от того, какой элемент в массиве я пытаюсь удалить.
Ответы
Свойство, установленное родительским продуктом, является неизменным, то есть вы не можете его изменить. Вам нужно использовать установщик геттера для общедоступного свойства.
_cartItems;
...
@api
get cartItems(){
return this._cartItems;
}
set cartItems(value){
this._cartItems = JSON.parse(JSON.stringify(value));
}
Обратите внимание , что я создал новую частную собственность с другим именем , т.е. _cartItems
.
Теперь вы можете выполнять все операции и обновлять файл _cartItems
. Чтобы отправить обновленные данные в родительский объект, вам необходимо отправить настраиваемое событие от дочернего элемента.