Shopware 6中订阅init()内发布的事件无响应问题
问题:Shopware 6 JS插件无法订阅目标插件的init事件
问题场景
我在Shopware 6中开发了一个JS插件,用于订阅另一个JS插件的两个事件:一个在用户与页面交互后触发,另一个在目标插件的init()方法末尾触发。前者工作正常,但后者完全无响应。两个$emitter.publish调用传入的参数一致,且我插件中使用了同一个处理方法。
相关代码
我的插件代码
main.js
import MyPlugin from "./my-plugin/my-plugin.plugin"; const PluginManager = window.PluginManager; PluginManager.register("MyPlugin", MyPlugin);
./my-plugin/my-plugin.plugin.js
import Iterator from "src/helper/iterator.helper"; export default class MyPlugin extends window.PluginBaseClass { init() { const configuratorPlugins = window.PluginManager.getPluginInstances("TargetPlugin"); Iterator.iterate(configuratorPlugins, (instance) => { // 无效... instance.$emitter.subscribe("init", this.onEvent.bind(this)); // 有效... instance.$emitter.subscribe( "otherEvent", this.onEvent.bind(this) ); }); } onEvent(event) { // 执行操作... } }
目标插件代码(target-plugin.plugin.js)
init() { // ... this.$emitter.publish('init', this.createCurrentState()); }
已排查情况
init事件未被包裹在if语句中,发布前通过console.log测试this.createCurrentState()结果正常- 调用
PluginManager.getPluginList()确认,目标插件在我的插件注册前已存在于列表中
尝试过的解决方案(基于Michele的回答)
我尝试通过配置依赖确保加载顺序,但问题仍未解决:
const PluginManager = window.PluginManager; // ... const options = { dependencies: [...PluginManager.getPluginInstance("TargetPlugin")], // 为空 }; console.log(typeof PluginManager.getPluginInstance("TargetPlugin")); // object console.log(Object.keys(PluginManager.getPluginInstance("TargetPlugin")).length) // 0 console.log(PluginManager.getPluginInstance("TargetPlugin").size) // undefined console.log(PluginManager.getPluginInstance("TargetPlugin") instanceof Map) // false – PluginManager.getPluginInstances的文档注释为@returns {Map|null} console.log(Array.isArray(PluginManager.getPluginInstance("TargetPlugin"))) // true console.log(PluginManager.getPluginInstance("TargetPlugin").length) // 0 PluginManager.register("MyPlugin", MyPlugin, document, options);
可能的解决方向
- 事件发布时机问题:目标插件的
init事件在你的插件订阅前就已触发。即便目标插件在插件列表中存在,它的init方法可能早于你的插件init执行,导致订阅滞后。 - 依赖配置修正:无需通过实例获取依赖,直接指定插件名称即可让Shopware保证加载顺序:
const options = { dependencies: ['TargetPlugin'] }; PluginManager.register("MyPlugin", MyPlugin, document, options); - 事件名称冲突排查:
init是通用事件名,可能存在被其他插件覆盖或提前消费的情况,可尝试给目标插件的init事件重命名为更独特的标识(如target-plugin-init)。 - 订阅时机调整:如果依赖配置无效,可监听Shopware的
plugin-initialized事件,在目标插件实例化完成后再订阅:init() { window.PluginManager.on('plugin-initialized', (event) => { if (event.detail.pluginName === 'TargetPlugin') { const instance = event.detail.instance; instance.$emitter.subscribe("init", this.onEvent.bind(this)); instance.$emitter.subscribe("otherEvent", this.onEvent.bind(this)); } }); }
内容的提问来源于stack exchange,提问作者Carsten
相关产品推荐
相关产品推荐

