实现步骤与关键代码
步骤 | 描述 | 代码示例 |
---|---|---|
1.安装PubSubJS | 通过npm安装依赖库 | plaintext 复制 npminstallpubsub-js |
2.创建PubSub服务 | 封装全局消息管理逻辑 | ```javascript |
//app/services/pubsub.js | ||
importPubSubfrom'pubsub-js'; | ||
exportdefaultclassPubSubService{ | ||
subscribe(topic,callback){ |
plaintext复制returnPubSub.subscribe(topic,callback);
}
publish(topic,data){
PubSub.publish(topic,data);
}
}
复制|**3.组件订阅消息**|在Todos列表组件中监听新增任务|```javascript //app/components/todo-list.js importComponentfrom'@glimmer/component'; import{injectasservice}from'@ember/service'; exportdefaultclassTodoListextendsComponent{ @servicepubsub; constructor(){ super(...arguments); this.subscription=this.pubsub.subscribe('TODO_ADDED',(msg,data)=>{ this.todos.push(data); }); } //销毁时取消订阅 willDestroy(){ this.pubsub.unsubscribe(this.subscription); super.willDestroy(...arguments); } } ``````| |**4.组件发布消息**|在创建Todo的表单提交后触发广播|```javascript //app/components/todo-form.js importComponentfrom'@glimmer/component'; import{action}from'@ember/object'; exportdefaultclassTodoFormextendsComponent{ @action handleSubmit(title){ //调用RailsAPI创建Todo fetch('/api/todos',{ method:'POST', headers:{'Content-Type':'application/json'}, body:JSON.stringify({title}) }) .then(res=>res.json()) .then(data=>{ this.pubsub.publish('TODO_ADDED',data);//触发全局事件 }); } } ``````| ###与Rails后端的协同优化 1.**异步任务通知** -在Rails控制器中,任务创建成功后通过ActionCable推送消息到前端,触发PubSub事件。 ```ruby #app/controllers/todos_controller.rb defcreate @todo=Todo.create(todo_params) if@todo.save ActionCable.server.broadcast('todos_channel',{action:'added',data:@todo}) head:ok else renderjson:@todo.errors,status::unprocessable_entity end end `````` 2.**前端消息监听** -通过WebSocket接收后端事件并转换为PubSub消息。 ```javascript //app/services/action-cable.js importCablefrom'actioncable'; exportdefaultclassActionCableService{ connect(){ constcable=Cable.createConsumer(); cable.subscriptions.create({channel:'TodosChannel'},{ received(data){ if(data.action==='added'){ this.pubsub.publish('TODO_ADDED',data.data); } } }); } } `````` ###注意事项 -**内存泄漏预防**:确保组件销毁时通过`willDestroy`取消订阅。 -**命名规范**:使用唯一且语义化的事件名(如`TODO_UPDATED:123`)。 -**性能优化**:对高频事件添加防抖(debounce)或节流(throttle)。 此方案通过PubSubJS实现了Ember组件与Rails后端的松耦合通信,同时支持多组件对同一事件的响应。