簡體   English   中英

對象屬性的值在 Ember 的本地存儲中沒有改變

[英]The value of object's property is not being changed in the Local Storage in Ember

我正在 Ember 中建立一個商店,其中包含當用戶單擊添加到購物車按鈕時添加到本地存儲的產品列表。 每個產品都是一個對象,它有一個名為ordered_quantity的屬性,當用戶嘗試從購物車中刪除產品時,我試圖更改此屬性的值。 (例如: ordered quantity: 8 ,單擊按鈕時應為7 )。

我的服務文件中有以下代碼:

remove(item) {
  let new_arr = this.get('items');
  let elementIndex = new_arr.findIndex(obj => {
    return obj.id === item.id;
  });

  if (elementIndex !== -1) {
    new_arr[elementIndex].ordered_quantity = new_arr[elementIndex].ordered_quantity - 1;
  } 
  this.set('cart.items', new_arr);
}

我正在使用本地存儲插件( https://github.com/funkensturm/ember-local-storage#methods

我有以下行動:

actions: {
  removeFromCart(){
    this.get('cart').remove(this.product);
  }
}

當我嘗試運行以下代碼時,出現錯誤:

未捕獲的錯誤:斷言失敗:您試圖將 [object Object].ordered_quantity 更新為“7”,但它正在被跟蹤上下文跟蹤,例如模板、計算屬性或觀察者。 為了確保上下文正確更新,更新時必須使屬性無效。 您可以將該屬性標記為@tracked ,或使用@ember/object#set來執行此操作。

我嘗試使用這樣的 set 函數:

let updated = item.ordered_quantity - 1;
set(item, 'ordered_quantity', updated);

https://api.emberjs.com/ember/release/functions/@ember%2Fobject/set並且代碼按預期運行沒有錯誤,但我的屬性ordered_quantity的值未在本地存儲中更新。

您需要根據您的用例調整set函數:

remove(item) {
  let new_arr = this.get('items');
  let elementIndex = new_arr.findIndex(obj => {
    return obj.id === item.id;
  });

  if (elementIndex !== -1) {
    set(new_arr[elementIndex], 'ordered_quantity', new_arr[elementIndex].ordered_quantity - 1);
  } 
  this.set('cart.items', new_arr);
}

基於@Lux 的原始答案(以及針對 Ember 3.16+ 時代的更新),我想補充一點,您可以使用函數式編程模式來稍微清理一下:

如果在您的cart Service 中,items 是@tracked ,如下所示:

import Service from '@ember/service';
import { tracked } from '@glimmer/tracking';

export default class CartService extends Service {
  @tracked items = [];
}

注意:假設沒有跟蹤ordered_quantity

remove(item) {
  for (let obj of this.items) {
    if (item.id !== obj.id) continue;

    // set must be used because quantity is not known to the tracking system
    set(obj, 'ordered_quantity', obj.ordered_quantity - 1);
  });

  // invalidate the reference on the card service so that all things that
  // reference cart.items re-compute
  this.cart.items = this.items;
}

這是一個現場演示: https : //ember-twiddle.com/e18433b851091b527512e27ae792640c?openFiles=components.demo%5C.js%2C

還有一個實用程序插件,它允許與數組、對象等進行更符合人體工程學的交互: https : //github.com/pzuraq/tracked-built-ins

上面的代碼看起來像這樣:

import Service from '@ember/service';
import { tracked } from '@glimmer/tracking';
import { TrackedArray } from 'tracked-built-ins';

export default class CartService extends Service {
  @tracked items = new TrackedArray([]);
}

然后在您的組件中:

remove(item) {
  for (let obj of this.items) {
    if (item.id !== obj.id) continue;

    // set must be used because quantity is not known to the tracking system
    set(obj, 'ordered_quantity', obj.ordered_quantity - 1);
  });
}

這是一個現場演示: https : //ember-twiddle.com/23c5a7efdb605d7b5fa9cd9da61c1294?openFiles=services.cart%5C.js%2C

然后,您可以更進一步,並為您的“項目”添加跟蹤。

那么您的 remove 方法將如下所示:

remove(item) {
  for (let obj of this.items) {
    if (item.id !== obj.id) continue;

    obj.ordered_quantity = obj.ordered_quantity - 1;
  });
}

這是一個現場演示: https : //ember-twiddle.com/48c26e2e0f0e5f3ac7685e4bdc0eda4e?openFiles=components.demo%5C.js%2C

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM