Dodawanie dwóch takich samych obiektów do tablicy

Dodawanie dwóch takich samych obiektów do tablicy
JD
  • Rejestracja:około 19 lat
  • Ostatnio:około godziny
0

Hej,

tworzę generowanie dokumenty zamówienia sprzedaży. Mam dropdowna z wyborem towaru, pole input z ilością i przycisk dodaj.
Dodaję coś takiego:

Kopiuj
export interface ISku {
  id: number;
  code: string;
  name: string;
  codeName: string;
  uom: string;
  quantity: number;
}

do tablicy

Kopiuj
const orderPositions = ref<Array<ISku>>([]);

dodaje towar do zamówienia w taki sposób

Kopiuj
const sku = ref<ISku>({
  id: 0,
  code: "",
  name: "",
  codeName: "",
  uom: "",
  quantity: 0,
});

// ta metoda rusza gdy wybiorę towar z dropdowna
const pickSku = (value) => {
  let item = skus.value.filter((item) => {
    return item.id == value;
  });

  item[0].quantity = 1;

  sku.value = item[0];
};    

// tutaj gdy klik w button "dodaj pozycje"
const addOrderPosition = () => {
  if (sku.value?.quantity) sku.value.quantity = skuQuantity.value;

  orderPositions.value.push(sku.value);
};  

wyświetlam tak

Kopiuj
<tbody>
  <tr v-for="(row, index) in orderPositions" :key="index">
    <td>{{ row.code }}</td>
    <td>{{ row.name }}</td>
    <td>
      <el-input-number
        v-model="row.quantity"
      />
    </td>
    <td>
      <a @click="deleteOrderPosition(row.id)" class="menu-link px-3">
        <i class="fa fa-trash text-danger"></i>
      </a>
    </td>
  </tr>
</tbody>

problem mam taki, że gdy dodam dwa razy ten sam towar i zmieniam jednemu z nich wartość quantity w inpucie w tabelce powyżej. Steruje obiema wartościami jednocześnie.

Próbowałem do ISku dodać property z jakimś generowanym GUIDEM ale nie dało rezultatów. Szybko robiłem i chyba zrobię to raz jeszcze dla testu.
GUID = jakiś id unikalny wiersza by się przydał również dla operacji usunięcia pozycji. Bo w tej chwili szukając po sku.id usuwam 1szy znaleziony co w przypadku 2 takich samych nie da rady działać poprawnie.

Zresztą użycie w pętli :key="index" - próbowałem użyć tego.

edytowany 1x, ostatnio: Riddle
KA
  • Rejestracja:prawie 20 lat
  • Ostatnio:mniej niż minuta
  • Lokalizacja:Gorlice
1

Możliwe, że problem jest z tym:

Kopiuj
  let item = skus.value.filter((item) => {
    return item.id == value;
  });

Musisz robić kopię obiektu poczytaj choćby https://devszczepaniak.pl/kopiowanie-obiektow-w-javascript/


Nie odpowiadam na PW w sprawie pomocy programistycznej.
Pytania zadawaj na forum, bo:
od tego ono jest ;) | celowo nie zawracasz gitary | przeczyta to więcej osób a więc większe szanse że ktoś pomoże.
LukeJL
  • Rejestracja:około 11 lat
  • Ostatnio:2 minuty
  • Postów:8423
0
Kopiuj
  let item = skus.value.filter((item) => {
    return item.id == value;
  });

  item[0].quantity = 1;

jeśli zależy ci na wyszukaniu obiektu, to masz do tego metodę find
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find

wtedy powyższy kod można zapisać bez potrzeby tworzenia dodatkowej tablicy:

Kopiuj
  let item = skus.value.find((item) => {
    return item.id == value;
  });

  item.quantity = 1;

(nie mówię, że kod powyżej będzie poprawny w kontekście całej aplikacji (w szczególności nic on nie zmieni w konktekście tego, o co pytasz), raczej chodzi mi tylko o ten konkretny pattern, że zamiast tworzyć nową tablicę przez filter i robić item[0], to można od razu użyć find i mieć od razu ten konkretny element)

nie kumam też, czemu robisz skus.value, czy nie powinieneś używać samego skus?

Kopiuj
skus.find(......)

Ale to moje przypuszczenie tylko, bo nie widzę całego kodu.

Poza tym tak jak przedmówca wspomniał, potrzebna ci kopia obiektu.


edytowany 2x, ostatnio: LukeJL
JD
skus.value -> tak należy dostać się do zmiennej zadeklarowanej jako ref() w VueJs
JD
  • Rejestracja:około 19 lat
  • Ostatnio:około godziny
0

@LukeJL: to fakt aby to uprościć
@kAzek: to dobry trop jednak nie wychodzi
przerobiłem jednak nadal dodanie tego samego obiektu powoduje mój problem. Dodawanie wszystkich innych towarów działa poprawnie.

Kopiuj
    const pickSku = (value) => {
      let item = skus.value.find((item) => {
        return item.id == value;
      });

      // we are sure that item is always found so non-null assertion operator is used to avoid "Object is possibly 'undefined'."
      item!.quantity = 1;

      //Object.assign({}, item);
      //{ ...item[0] };
      sku.value = JSON.parse(JSON.stringify(item));
    };
edytowany 1x, ostatnio: john_doe
LukeJL
  • Rejestracja:około 11 lat
  • Ostatnio:2 minuty
  • Postów:8423
1
john_doe napisał(a):
  // we are sure that item is always found so non-null assertion operator is used to avoid "Object is possibly 'undefined'."
  item!.quantity = 1;

Tylko, że działa jedynie na poziomie kompilacji TypeScripta. Jednak w dalszym ciągu item mógłby być undefined, jeśli nie zostałby znaleziony w tablicy:

Kopiuj
     let item = skus.value.find((item) => {
        return item.id == value;
      });

a wtedy wyskoczy wyjątek w czasie odpalania programu.

Więc lepszą praktyką byłoby upewnienie się, czy faktycznie item został znaleziony:

Kopiuj
  let item = skus.value.find((item) => {
    return item.id == value;
  });
  if (item) {
     item.quantity = 1;
  }

KA
  • Rejestracja:prawie 20 lat
  • Ostatnio:mniej niż minuta
  • Lokalizacja:Gorlice
0

Może tak:

Kopiuj
orderPositions.value.push(JSON.parse(JSON.stringify(sku.value)));

Nie odpowiadam na PW w sprawie pomocy programistycznej.
Pytania zadawaj na forum, bo:
od tego ono jest ;) | celowo nie zawracasz gitary | przeczyta to więcej osób a więc większe szanse że ktoś pomoże.
JD
dokładnie tak zrobiłem i działa

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.