VueJS Typescript WebPack, невозможно удалить объект из массива с помощью склеивания или удаления - PullRequest
0 голосов
/ 30 октября 2018

Я пытаюсь удалить объект из массива в vueJS, но это невозможно.

Я много чего читаю и читаю какое-то решение по stackoverflow, но у меня ничего не получается.

У меня есть фальшивый список в моем компоненте vue.html:

<div class="custo-list-c">
  <div v-for="(item, index) in valuesFounded" 
    @click="addItem(item)"
    v-bind:class="{ 'selected': itemSelected(item) }">
    {{ item.value }}
    <span v-if="itemSelected(item)">
      <i class="fa fa-remove" @click="itemDeleted(item)"></i>
    </span>
  </div>
</div>

И мой компонент выглядит примерно так:

import Vue from 'vue';
import Component from 'vue-class-component';
import { Prop, Watch, Emit } from "vue-property-decorator";

@Component({
  name: 'custolist-component',
  template: require('./custo-list.component.vue.html'),
  components: {}
})
export default class CustoListComponent extends Vue {

  public custoListActive: boolean = false;
  public valuesFounded: Array<{key: string, value: string}> = [];

  public selectedItems_: Array<{key: string, value: string}> = [];

  @Prop() list;
  @Watch('list') onListChanged(newList, oldList) {
    // this.list = newList;
  }

  @Prop() placeholder;
  @Watch('placeholder') onPlaceholderChanged(newPlaceholder, oldPlaceholder) {
    // console.log(newPlaceholder);
  }

  @Prop() disabled;
  @Watch('disabled') onDisabledChanged(newDisabled, oldDisabled) {
    // console.log(newPlaceholder);
  }

  public open(event) {
    this.custoListActive = true;
    if (!event.target.value) {
      this.valuesFounded = this.list;
    } else {
      this.valuesFounded = [];
      const re = new RegExp(event.target.value, 'ig');
      for (var i=0; i<this.list.length; i++) {
        if (this.list[i].key.match(re) || this.list[i].value.match(re)) {
          this.valuesFounded.push(this.list[i]);
        }
      }
    }
  }

  public addItem(item: {key: string, value: string}) {

    if (!this.isSelectedItem_(item)) {
      this.selectedItems_.push(item);
      // this.custoListActive = false;
    };

    this.$emit('itemclicked', item);
  }

  public itemSelected(item) {
    return this.isSelectedItem_(item);
  }

  public itemDeleted(item) {
    for (var i=0; i<this.selectedItems_.length; i++) {
      if (item.key == this.selectedItems_[i].key) {
        this.selectedItems_.splice(i, 1);
        break;
      }
    }
    this.$emit('itemdeleted', item);
  }

  private isSelectedItem_(item) {
    const filtered = this.selectedItems_.filter(m => {
      return m.key == item.key;
    });

    return filtered.length > 0;
  }
}

но когда я делаю this.selectedItems_.splice(i, 1);, это не работает !!

Спасибо за вашу помощь

Больше точности относительно моего кода. Вот метод, где я удаляю элемент из моего массива:

public itemDeleted(item) {
  const filtered = this.selectedItems_.filter(m => {
    return m.key != item.key;
  });

  console.log(filtered, this.selectedItems_.length);
  this.selectedItems_ = filtered;
  console.log(this.selectedItems_, this.selectedItems_.length);

  this.$emit('itemdeleted', item);
}

И результат в консоли

Консоль

Что не так?

Еще один тест:

  public itemDeleted(item) {
    this.selectedItems_ = this.selectedItems_.filter(m => {
      return m.key != item.key;
    });

    this.selectedItems_.splice(this.selectedItems_.length);
    console.log(this.selectedItems_, this.selectedItems_.length);
    this.selectedItems_ = [];
    console.log(this.selectedItems_, this.selectedItems_.length);

    this.$emit('itemdeleted', item);
  }

результат:

Консоль

Может быть ошибка VueJS

Извините, это была моя вина, замените

<i class="fa fa-remove" @click="itemDeleted(item)"></i>

по

<i class="fa fa-remove" v-on:click.stop="itemDeleted(item)"></i>

1 Ответ

0 голосов
/ 30 октября 2018

Наличие нескольких шагов для нахождения значения с комбинацией цикла for и оператора if снижает читабельность и предсказуемость кода. Кроме того, вызов метода мутации массива splice может не инициировать реактивное обновление этого свойства.

Я бы предложил использовать фильтр и переназначить selectedItems_ внутри itemDeleted метода следующим образом:

public itemDeleted(item) {
  this.selectedItems_ = this.selectedItems_.filter(selectedItem => selectedItem.key !== item.key)
  this.$emit('itemdeleted', item);
}

Таким образом, после выполнения метода selectedItems_ будет состоять из всех предыдущих элементов, кроме одного, предоставленного в качестве аргумента метода, и все зависимые свойства будут пересчитаны.

...