Shopware 6自定义组件删除确认模态框无法弹出问题排查
问题排查与修复方案
1. 修复Twig模板DOM结构错误
你的my-component.html.twig中<sw-entity-listing>标签未闭合,导致后续模态框代码被错误嵌套,无法正常渲染。需补充闭合标签:
<sw-entity-listing v-if="templist" v-bind:items="templist" v-bind:repository="repository" v-bind:showSelection="false" v-bind:columns="columns"> <template slot="actions" slot-scope="{ item }"> <sw-context-menu-item variant="danger" @click="onDelete(item)" > Delete </sw-context-menu-item> </template> </sw-entity-listing> <!-- 补充该闭合标签 -->
2. 调整模态框位置(建议)
将删除模态框移到<sw-page>根层级下,避免被其他组件作用域影响,确保Vue能正确控制v-if显示:
{% block custom_list %} <sw-page class="custom_list"> <!-- 头部、操作按钮等原有代码 --> <template slot="content"> {% block plugin_entry_content %} <sw-entity-listing ...> <!-- 列表内容与操作 --> </sw-entity-listing> {% endblock %} </template> <!-- 模态框移至sw-page内部根位置 --> {% block plugin_entry_modal_delete %} <sw-modal v-if="showEntryDeleteModal" variant="small" :title="$t('custom_list.modal.deleteTitle')" @modal-close="onCancelEntryDelete" > <!-- 模态框内容 --> </sw-modal> {% endblock %} </sw-page> {% endblock %}
3. 补充组件初始化逻辑
你的index.js缺少仓库初始化和数据加载的钩子,导致templist为空、列表无法渲染,点击事件无法触发:
created() { this.repository = this.repositoryFactory.create('your_entity_technical_name'); // 替换为你的实体技术名称 this.loadItems(); }, computed: { templist() { return this.blacklist?.items || []; } }
4. 简化方法逻辑(可选)
可以直接在onDelete中赋值控制模态框,减少冗余方法:
onDelete(item) { this.deleteEntryId = item.id; this.showEntryDeleteModal = true; }, onCancelEntryDelete() { this.deleteEntryId = null; this.showEntryDeleteModal = false; }
最终修复后关键代码片段
my-component.html.twig
{% block custom_list %} <sw-page class="custom_list"> {% block custom_list_smart_bar_header %} <!-- 原头部代码不变 --> {% endblock %} {% block custom_list_smart_bar_actions %} <!-- 原操作按钮代码不变 --> {% endblock %} <template slot="content"> {% block plugin_entry_content %} <sw-entity-listing v-if="templist.length > 0" v-bind:items="templist" v-bind:repository="repository" v-bind:showSelection="false" v-bind:columns="columns"> <template slot="actions" slot-scope="{ item }"> <sw-context-menu-item variant="danger" @click="onDelete(item)" > {{ $t('custom_list.buttonDelete') }} </sw-context-menu-item> </template> </sw-entity-listing> <!-- 空状态提示 --> <div v-else class="sw-empty-state"> {{ $t('custom_list.emptyState') }} </div> {% endblock %} </template> {% block plugin_entry_modal_delete %} <sw-modal v-if="showEntryDeleteModal" variant="small" :title="$t('custom_list.modal.deleteConfirmTitle')" @modal-close="onCancelEntryDelete" > {% block plugin_entry_modal_delete_body %} <p>{{ $t('custom_list.modal.deleteConfirmMessage') }}</p> {% endblock %} {% block plugin_entry_modal_delete_footer %} <template #modal-footer> <sw-button size="small" @click="onCancelEntryDelete" > {{ $t('global.cancel') }} </sw-button> <sw-button size="small" variant="danger" @click="onConfirmEntryDelete" > {{ $t('global.delete') }} </sw-button> </template> {% endblock %} </sw-modal> {% endblock %} </sw-page> {% endblock %}
index.js
inject: [ 'repositoryFactory' ], data() { return { isLoading: false, repository: null, blacklist: null, showEntryDeleteModal: false, deleteEntryId: null }; }, created() { this.repository = this.repositoryFactory.create('your_entity_technical_name'); this.loadItems(); }, computed: { templist() { return this.blacklist?.items || []; } }, methods: { loadItems() { this.isLoading = true; this.repository.search(new Shopware.Data.Criteria(), Shopware.Context.api).then((result) => { this.blacklist = result; this.isLoading = false; }).catch(() => { this.isLoading = false; }); }, onDelete(item) { this.deleteEntryId = item.id; this.showEntryDeleteModal = true; }, onCancelEntryDelete() { this.deleteEntryId = null; this.showEntryDeleteModal = false; }, onConfirmEntryDelete() { this.showEntryDeleteModal = false; this.repository.delete(this.deleteEntryId, Shopware.Context.api) .then(() => { this.deleteEntryId = null; this.loadItems(); }).catch((error) => { Shopware.Utils.debug.error('Delete failed', error); this.$root.addNotification({ variant: 'error', title: this.$t('global.default.error'), message: this.$t('custom_list.error.deleteFailed') }); }); } }
内容的提问来源于stack exchange,提问作者mlodhi
相关产品推荐
相关产品推荐

