删除按钮在 vue-bootstrap> 中生成多个确认模式
Delete button spawning multiple confirm modals in vue-bootstrap>
希望通过在此循环中对模态进行唯一引用来解决此问题,尝试在末尾给引用一个 grade.id,但不适用于带有 b 模态引用的字符串插值,也试过 :ref.
这是 vue 文件中的代码,下面是它的截图,当我按下删除成绩时,它会显示所有模态,因为模态在一个循环中。
<template>
<div>
<b-form @submit="onSubmit" @reset="onReset">
<b-row>
<b-col class="underline">Add Grades</b-col>
</b-row>
<br />
<b-row>
<b-col>
<b-form-group
inline
label-cols-sm="4"
label-cols-lg="3"
id="input-group-1"
label="Select Farm:"
>
<b-form-select v-model="form.farm" :options="farms" required />
</b-form-group>
</b-col>
</b-row>
<b-row class="my-1">
<b-col>
<b-form-group label-cols-sm="4" label-cols-lg="3" label="name:">
<b-form-input
v-model="form.gradeName"
size="sm"
placeholder="name"
></b-form-input>
</b-form-group>
</b-col>
</b-row>
<b-row class="my-1">
<b-col>
<b-form-group
label-cols-sm="4"
label-cols-lg="3"
label="min weight(gms):"
>
<b-form-input
v-model="form.gradeMinWeight"
size="sm"
placeholder="minimum"
></b-form-input>
</b-form-group>
</b-col>
</b-row>
<b-row class="my-1">
<b-col>
<b-form-group
label-cols-sm="4"
label-cols-lg="3"
label="max weight(gms):"
>
<b-form-input
v-model="form.gradeMaxWeight"
size="sm"
placeholder="maximum"
></b-form-input>
</b-form-group>
</b-col>
</b-row>
<b-row class="my-1">
<b-col>
<b-form-group label-cols-sm="4" label-cols-lg="3" label="shape:">
<b-form-select v-model="form.gradeShape">
<option value="rounded">rounded</option>
<option value="flat">flat</option>
<option value="curve">curve</option>
</b-form-select>
</b-form-group>
</b-col>
<b-col>
<b-form-group label-cols-sm="4" label-cols-lg="3" label="dimension:">
<b-form-select v-model="form.gradeDimension">
<option value="rounded">seeds</option>
<option value="rounded">small</option>
<option value="flat">medium</option>
<option value="curve">large</option>
<option value="curve">extra large</option>
<option value="curve">jumbo</option>
</b-form-select>
</b-form-group>
</b-col>
</b-row>
<b-row>
<b-col>
<b-button type="submit" variant="primary" block>Add</b-button>
</b-col>
<b-col>
<b-button type="reset" variant="secondary" block>Cancel</b-button>
</b-col>
</b-row>
</b-form>
<br />
<b-row>
<b-col class="underline">My Grades</b-col>
</b-row>
<br />
<div v-if="grades.length > 0">
<b-card-group class="mb-4" v-for="grade in grades" :key="grade.id">
<b-card :title="getTitle(grade)">
<b-card-text class="list-card">
{{ getProperties(grade) }}
<span style="float: right">
<b-button
class="mr-1"
type="reset"
variant="danger"
@click="showModal"
size="sm"
>
<!-- Fix css to icon middle -->
<b-icon icon="trash-fill" size="is-small"></b-icon>
</b-button>
<b-modal
scrollable
id="modal-delete-grade"
ref=' `modal-delete-grade'
centered
@ok="actionDelete(grade.id)"
class="d-block text-center"
title="Confirm Delete Grade"
>
<p>
Confirm that you are about to delete grade
{{ getTitle(grade) }}
</p>
</b-modal>
</span>
</b-card-text>
</b-card>
</b-card-group>
</div>
</div>
</template>
<script>
import makeToast from "../../helper/toast";
import farmService from "../../service/FarmService";
import { getUser } from "@/helper/storage";
import userService from "@/service/UserService";
import DashEdit from "@/views/DashEdit";
import { contentMixin } from "@/mixins/contentMixin";
import { setupMixin } from "@/mixins/setupMixin";
export default {
name: "AddSetupGrade",
mixins: [contentMixin, setupMixin],
data() {
return {
farms: [],
grades: [],
form: {
farm: null,
gradeName: null,
gradeMinWeight: null,
gradeMaxWeight: null,
gradeShape: null,
gradeDimension: null,
},
};
},
mounted() {
this.getUserFarm();
this.getGrades();
},
created() {
this.getGrades();
},
methods: {
async onSubmit(evt) {
try {
evt.preventDefault();
let response = await farmService.addGrades({
name: this.form.gradeName,
farmId: this.form.farm.id,
properties: {
minWeight: this.form.gradeMinWeight,
maxWeight: this.form.gradeMaxWeight,
units: "gms",
shape: this.form.gradeShape,
dimension: this.form.gradeDimension,
},
});
if (response.status === 200) {
makeToast.call(
this,
"Success",
"Successfully created grade",
"success"
);
this.onReset();
this.getGrades();
}
} catch (e) {
console.log(`Error in creating grade. ${e}`);
makeToast.call(this, "Error", "Error adding grade", "danger");
}
},
onReset() {
this.form.gradeName = null;
this.form.gradeMinWeight = null;
this.form.gradeMaxWeight = null;
this.form.gradeShape = null;
this.form.gradeDimension = null;
},
async getUserFarm() {
try {
let { id: userId } = getUser();
let response = await userService.getFarmsOfUser(userId);
let farmList = response.data.data;
this.farms = farmList.map((each) => {
return {
value: { id: each.id, name: each.name },
text: each.name,
};
});
this.farms.push({ value: null, text: "Select Farm" });
} catch (e) {
console.log(`Error: ${e}`);
}
},
getTitle(grade) {
if (grade) {
return grade.name + " - " + grade.alias;
}
},
showModal(gradeId) {
this.$bvModal.show("modal-delete-grade");
},
keyValString(obj) {
return Object.entries(obj).reduce((str, [key, value], index) => {
if (value) {
if (str) str += ", ";
str += `${key}: ${value}`;
}
return str;
}, "");
},
getProperties(grade) {
return (
(grade && grade.properties && this.keyValString(grade.properties)) ||
"No properties on grade."
);
},
async getGrades() {
try {
let response = await farmService.getGrades();
this.grades = response.data.data;
} catch (e) {
console.log(e);
}
},
async actionDelete(id) {
try {
let response = await farmService.deleteGrade(id);
this.$bvModal.hide("modal-delete-grade");
this.getGrades();
} catch (e) {
console.log(e.response.data);
}
},
},
};
</script>
<style scoped>
.underline {
border-bottom: 2px solid currentColor;
border-bottom-color: #d3d3d3;
font-weight: bold;
font-size: 16px;
}
.list-card {
font-family: Open Sans;
font-size: 14px;
line-height: (48 / 24);
letter-spacing: -0.046em;
color: black;
}
.card-title {
font-size: 1em;
font-family: Open Sans;
}
</style>
您可以将模式移出循环。要传递点击成绩的数据,只需将其保存到您的数据中,例如作为“activeGrade”。在您的模式中,您显示“activeGrade”的数据。现在您可以使用点击的成绩特定数据打开(相同的)模式。
我稍微简化了您的代码以仅显示提出的问题:
<template>
<div class="hello">
<b-card-group class="mb-4" v-for="grade in grades" :key="grade.id">
<b-card :title="grade.title">
<b-card-text class="list-card">
Some Text (grade properties)
<span style="float: right">
<b-button
class="mr-1"
type="reset"
variant="danger"
@click="showModal(grade)"
size="sm">
<!-- Fix css to icon middle -->
<b-icon icon="trash-fill" size="is-small"></b-icon>
</b-button>
</span>
</b-card-text>
</b-card>
</b-card-group>
<b-modal v-if="activeGrade"
scrollable
id="modal-delete-grade"
centered
@ok="actionDelete(activeGrade.id)"
class="d-block text-center"
title="Confirm Delete Grade">
<p>
Confirm that you are about to delete grade
{{ activeGrade.title }}
</p>
</b-modal>
</div>
</template>
<script>
export default {
data() {
return {
grades: [
{ id: 1, title: 'Grate 1' },
{ id: 2, title: 'Grate 2' },
{ id: 3, title: 'Grate 3' },
],
activeGrade: null
}
},
methods: {
actionDelete(gradeId) {
console.log('delete ' + gradeId)
},
showModal(grade) {
this.activeGrade = grade
this.$nextTick(() => {
this.$bvModal.show("modal-delete-grade");
})
}
}
}
</script>
希望通过在此循环中对模态进行唯一引用来解决此问题,尝试在末尾给引用一个 grade.id,但不适用于带有 b 模态引用的字符串插值,也试过 :ref.
这是 vue 文件中的代码,下面是它的截图,当我按下删除成绩时,它会显示所有模态,因为模态在一个循环中。
<template>
<div>
<b-form @submit="onSubmit" @reset="onReset">
<b-row>
<b-col class="underline">Add Grades</b-col>
</b-row>
<br />
<b-row>
<b-col>
<b-form-group
inline
label-cols-sm="4"
label-cols-lg="3"
id="input-group-1"
label="Select Farm:"
>
<b-form-select v-model="form.farm" :options="farms" required />
</b-form-group>
</b-col>
</b-row>
<b-row class="my-1">
<b-col>
<b-form-group label-cols-sm="4" label-cols-lg="3" label="name:">
<b-form-input
v-model="form.gradeName"
size="sm"
placeholder="name"
></b-form-input>
</b-form-group>
</b-col>
</b-row>
<b-row class="my-1">
<b-col>
<b-form-group
label-cols-sm="4"
label-cols-lg="3"
label="min weight(gms):"
>
<b-form-input
v-model="form.gradeMinWeight"
size="sm"
placeholder="minimum"
></b-form-input>
</b-form-group>
</b-col>
</b-row>
<b-row class="my-1">
<b-col>
<b-form-group
label-cols-sm="4"
label-cols-lg="3"
label="max weight(gms):"
>
<b-form-input
v-model="form.gradeMaxWeight"
size="sm"
placeholder="maximum"
></b-form-input>
</b-form-group>
</b-col>
</b-row>
<b-row class="my-1">
<b-col>
<b-form-group label-cols-sm="4" label-cols-lg="3" label="shape:">
<b-form-select v-model="form.gradeShape">
<option value="rounded">rounded</option>
<option value="flat">flat</option>
<option value="curve">curve</option>
</b-form-select>
</b-form-group>
</b-col>
<b-col>
<b-form-group label-cols-sm="4" label-cols-lg="3" label="dimension:">
<b-form-select v-model="form.gradeDimension">
<option value="rounded">seeds</option>
<option value="rounded">small</option>
<option value="flat">medium</option>
<option value="curve">large</option>
<option value="curve">extra large</option>
<option value="curve">jumbo</option>
</b-form-select>
</b-form-group>
</b-col>
</b-row>
<b-row>
<b-col>
<b-button type="submit" variant="primary" block>Add</b-button>
</b-col>
<b-col>
<b-button type="reset" variant="secondary" block>Cancel</b-button>
</b-col>
</b-row>
</b-form>
<br />
<b-row>
<b-col class="underline">My Grades</b-col>
</b-row>
<br />
<div v-if="grades.length > 0">
<b-card-group class="mb-4" v-for="grade in grades" :key="grade.id">
<b-card :title="getTitle(grade)">
<b-card-text class="list-card">
{{ getProperties(grade) }}
<span style="float: right">
<b-button
class="mr-1"
type="reset"
variant="danger"
@click="showModal"
size="sm"
>
<!-- Fix css to icon middle -->
<b-icon icon="trash-fill" size="is-small"></b-icon>
</b-button>
<b-modal
scrollable
id="modal-delete-grade"
ref=' `modal-delete-grade'
centered
@ok="actionDelete(grade.id)"
class="d-block text-center"
title="Confirm Delete Grade"
>
<p>
Confirm that you are about to delete grade
{{ getTitle(grade) }}
</p>
</b-modal>
</span>
</b-card-text>
</b-card>
</b-card-group>
</div>
</div>
</template>
<script>
import makeToast from "../../helper/toast";
import farmService from "../../service/FarmService";
import { getUser } from "@/helper/storage";
import userService from "@/service/UserService";
import DashEdit from "@/views/DashEdit";
import { contentMixin } from "@/mixins/contentMixin";
import { setupMixin } from "@/mixins/setupMixin";
export default {
name: "AddSetupGrade",
mixins: [contentMixin, setupMixin],
data() {
return {
farms: [],
grades: [],
form: {
farm: null,
gradeName: null,
gradeMinWeight: null,
gradeMaxWeight: null,
gradeShape: null,
gradeDimension: null,
},
};
},
mounted() {
this.getUserFarm();
this.getGrades();
},
created() {
this.getGrades();
},
methods: {
async onSubmit(evt) {
try {
evt.preventDefault();
let response = await farmService.addGrades({
name: this.form.gradeName,
farmId: this.form.farm.id,
properties: {
minWeight: this.form.gradeMinWeight,
maxWeight: this.form.gradeMaxWeight,
units: "gms",
shape: this.form.gradeShape,
dimension: this.form.gradeDimension,
},
});
if (response.status === 200) {
makeToast.call(
this,
"Success",
"Successfully created grade",
"success"
);
this.onReset();
this.getGrades();
}
} catch (e) {
console.log(`Error in creating grade. ${e}`);
makeToast.call(this, "Error", "Error adding grade", "danger");
}
},
onReset() {
this.form.gradeName = null;
this.form.gradeMinWeight = null;
this.form.gradeMaxWeight = null;
this.form.gradeShape = null;
this.form.gradeDimension = null;
},
async getUserFarm() {
try {
let { id: userId } = getUser();
let response = await userService.getFarmsOfUser(userId);
let farmList = response.data.data;
this.farms = farmList.map((each) => {
return {
value: { id: each.id, name: each.name },
text: each.name,
};
});
this.farms.push({ value: null, text: "Select Farm" });
} catch (e) {
console.log(`Error: ${e}`);
}
},
getTitle(grade) {
if (grade) {
return grade.name + " - " + grade.alias;
}
},
showModal(gradeId) {
this.$bvModal.show("modal-delete-grade");
},
keyValString(obj) {
return Object.entries(obj).reduce((str, [key, value], index) => {
if (value) {
if (str) str += ", ";
str += `${key}: ${value}`;
}
return str;
}, "");
},
getProperties(grade) {
return (
(grade && grade.properties && this.keyValString(grade.properties)) ||
"No properties on grade."
);
},
async getGrades() {
try {
let response = await farmService.getGrades();
this.grades = response.data.data;
} catch (e) {
console.log(e);
}
},
async actionDelete(id) {
try {
let response = await farmService.deleteGrade(id);
this.$bvModal.hide("modal-delete-grade");
this.getGrades();
} catch (e) {
console.log(e.response.data);
}
},
},
};
</script>
<style scoped>
.underline {
border-bottom: 2px solid currentColor;
border-bottom-color: #d3d3d3;
font-weight: bold;
font-size: 16px;
}
.list-card {
font-family: Open Sans;
font-size: 14px;
line-height: (48 / 24);
letter-spacing: -0.046em;
color: black;
}
.card-title {
font-size: 1em;
font-family: Open Sans;
}
</style>
您可以将模式移出循环。要传递点击成绩的数据,只需将其保存到您的数据中,例如作为“activeGrade”。在您的模式中,您显示“activeGrade”的数据。现在您可以使用点击的成绩特定数据打开(相同的)模式。
我稍微简化了您的代码以仅显示提出的问题:
<template>
<div class="hello">
<b-card-group class="mb-4" v-for="grade in grades" :key="grade.id">
<b-card :title="grade.title">
<b-card-text class="list-card">
Some Text (grade properties)
<span style="float: right">
<b-button
class="mr-1"
type="reset"
variant="danger"
@click="showModal(grade)"
size="sm">
<!-- Fix css to icon middle -->
<b-icon icon="trash-fill" size="is-small"></b-icon>
</b-button>
</span>
</b-card-text>
</b-card>
</b-card-group>
<b-modal v-if="activeGrade"
scrollable
id="modal-delete-grade"
centered
@ok="actionDelete(activeGrade.id)"
class="d-block text-center"
title="Confirm Delete Grade">
<p>
Confirm that you are about to delete grade
{{ activeGrade.title }}
</p>
</b-modal>
</div>
</template>
<script>
export default {
data() {
return {
grades: [
{ id: 1, title: 'Grate 1' },
{ id: 2, title: 'Grate 2' },
{ id: 3, title: 'Grate 3' },
],
activeGrade: null
}
},
methods: {
actionDelete(gradeId) {
console.log('delete ' + gradeId)
},
showModal(grade) {
this.activeGrade = grade
this.$nextTick(() => {
this.$bvModal.show("modal-delete-grade");
})
}
}
}
</script>