简体   繁体   中英

VueJS Typescript WebPack, impossible to remove object from array with splice or delete

i try to remove a object from array in vueJS but this is impossible.

I tyr a lot of thing and read some solution on stackoverflow but nothing work for me.

I have a fake list like this in my vue.html component :

<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>

And my component look something like this :

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;
  }
}

but when i do this.selectedItems_.splice(i, 1); that does not work !!

Thank for your help

More precisions about my code. Here the method where i remove item from my array :

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);
}

And the result in the console

console

What's wrong?

Another test :

  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);
  }

result :

console

May be a bug VueJS

Sorry, it was my fault, replace

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

by

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

Having multiple steps of finding value with combination of for loop and if statement reduces readability and code predictability. In addition, invoking array mutating method splice may not trigger reactive update of this property.

I'd suggest to use filter and re-assign selectedItems_ inside itemDeleted method as follows:

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

This way, after method execution, selectedItems_ will consist of all previous items except the one provided as an argument to the method and all dependent properties will be re-computed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM