从数组中删除项目:错误的项目被删除

时间:2019-08-19 14:41:59

标签: javascript vuejs2 vue-cli-3

我有一个帖子页面,其中包含媒体附件列表。我希望用户单击“删除”链接时能够手动删除附件。该事件正在运行,但是,问题是要删除的实际项目不是被单击的项目!我在做什么错了?

这里是我的代码和现场演示:[codesandbox](单击POSTS->选择帖子ID以查看帖子详细信息->单击EDIT post

  

EditPost.vue <template>部分:

...snip..
    <ul>
      <li>Media Attachments
        <template>
          <ul v-if="attachmentsFileNames && attachmentsFileNames.length">
            <li v-for="(mediaAttachment, index) in attachmentsFileNames" :key="index">
              <a href="#">{{ mediaAttachment }}</a>&nbsp;
              <button @click.prevent="deleteMediaAttachment(mediaAttachment, index)">Delete me!</button>
            </li>
          </ul>
          <p v-else>No Media Attachments</p>
        </template>
      </li>
    </ul>
  

EditPost.vue <script>

...snip..
data() {
    return {
      post: {},
      editPostFormIsVis: false,
      attachmentsArray: attachments
    };
  },
  created() {
    this.getPost();
  },
  methods: {
    getPost() {
      axios
        .get(
          "https://jsonplaceholder.typicode.com/posts/" + this.$route.params.id
        )
        .then(resp => {
          this.post = resp.data;
        })
        .catch(err => {
          console.log(err);
        });
    },
    editPost() {
      this.editPostFormIsVis = true;
    },
deleteMediaAttachment: function(item, index) {
      if (this.attachmentsArray.attachments[index] === item) {
        // The template passes index as the second parameter to avoid indexOf,
        // it will be better for the performance especially for one large array
        // (because indexOf actually loop the array to do the match)
        this.attachmentsArray.attachments.splice(index, 1);
      } else {
        let found = this.attachmentsArray.attachments.indexOf(item);
        this.attachmentsArray.attachments.splice(found, 1);
      }
    }
  },
  computed: {
    emailAttachmentsFileNames() {
      if (this.attachmentsArray.emailAttachments) {
        const emailAttachmentsFileNameArray = this.attachmentsArray.emailAttachments.map(
          item => {
            const tokens = item.split("/");
            return tokens[tokens.length - 1];
          }
        );
        return emailAttachmentsFileNameArray;
      } else {
        return null;
      }
    },
    attachmentsFileNames() {
      if (this.attachmentsArray.attachments) {
        const attachmentsFileNameArray = this.attachmentsArray.attachments.map(
          item => {
            const tokens = item.split("/");
            return tokens[tokens.length - 1];
          }
        );
        return attachmentsFileNameArray;
      } else {
        return null;
      }
    }
  }
...snip...

2 个答案:

答案 0 :(得分:1)

将您的deleteMediaAttachment函数更改为

deleteMediaAttachment: function(item, index) {
  this.attachmentsArray.attachments.splice(index, 1);
},

答案 1 :(得分:0)

您的问题是您从attachmentsFileNames发送项目,并尝试将其与原始attachments数组中的项目匹配。第一个包含文件名,第二个包含完整路径,因此它们将不匹配。例如:

console.log(item);                                     // star_wars_luke.jpeg
console.log(this.attachmentsArray.attachments[index]); // attachments/2019/201900002020/star_wars_luke.jpeg

这就是为什么this.attachmentsArray.attachments[index] === itemfalse,然后this.attachmentsArray.attachments.indexOf(item)返回-1的原因,因此this.attachmentsArray.attachments.splice(-1, 1)总是删除数组中的最后一项。

自从attachmentsFileNames解析this.attachmentsArray.attachments数组以来,您可以正确地依赖于index对应的数组,因此甚至不需要这些检查。只需删除它们并运行this.attachmentsArray.attachments.splice(index, 1),它应该可以工作。