从数组中删除项目:删除了错误的项目
Removing an item from array: Wrong item being removed
我有一个包含媒体附件列表的 post 页面。我希望用户在单击 "delete" link 时能够手动删除附件。此事件有效,但是,问题是被删除的实际项目不是被点击的项目!我做错了什么?
这是我的代码和现场演示:[codesandbox](单击帖子-->选择一个 post ID 以查看 post 详细信息 -- > 点击编辑 post)
EditPost.vue <template>
section:
...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>
<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...
将您的 deleteMediaAttachment 函数更改为
deleteMediaAttachment: function(item, index) {
this.attachmentsArray.attachments.splice(index, 1);
},
您的问题是您从 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] === item
是 false
,然后是 this.attachmentsArray.attachments.indexOf(item)
returns -1
,因此,this.attachmentsArray.attachments.splice(-1, 1)
总是删除列表中的最后一项数组。
由于您自己从 this.attachmentsArray.attachments
解析了 attachmentsFileNames
数组,您可以依赖正确对应的 index
,因此甚至不需要这些检查。只需删除它们和 运行 this.attachmentsArray.attachments.splice(index, 1)
就可以了。
我有一个包含媒体附件列表的 post 页面。我希望用户在单击 "delete" link 时能够手动删除附件。此事件有效,但是,问题是被删除的实际项目不是被点击的项目!我做错了什么?
这是我的代码和现场演示:[codesandbox](单击帖子-->选择一个 post ID 以查看 post 详细信息 -- > 点击编辑 post)
EditPost.vue
<template>
section:
...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>
<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...
将您的 deleteMediaAttachment 函数更改为
deleteMediaAttachment: function(item, index) {
this.attachmentsArray.attachments.splice(index, 1);
},
您的问题是您从 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] === item
是 false
,然后是 this.attachmentsArray.attachments.indexOf(item)
returns -1
,因此,this.attachmentsArray.attachments.splice(-1, 1)
总是删除列表中的最后一项数组。
由于您自己从 this.attachmentsArray.attachments
解析了 attachmentsFileNames
数组,您可以依赖正确对应的 index
,因此甚至不需要这些检查。只需删除它们和 运行 this.attachmentsArray.attachments.splice(index, 1)
就可以了。