-
Notifications
You must be signed in to change notification settings - Fork 57
Message
TANG edited this page Dec 14, 2016
·
8 revisions
组件通信对解决复杂的交互也有很大的用处,sugar 支持冒泡通信(fire)、广播通信(broadcast)、一对一通信(notify) 和全局广播通信(globalCast) 4 种通信方式,这四种通信方式能解决大部分的组件通信需求。
消息的接收统一在组件内部用 on + 消息名称首字母大写的函数方法来接收(如:onMessage)。
冒泡通信要求通信的组件之间是"父子关系",消息由子组件发出,父组件接收,并且消息会"冒泡"到父组件的父组件:
var ComponentOne = sugar.Component.extend({ init: function (config) { this.Super('init', config); }, afterRender: function () { // fire 会将消息发到父组件,以及父组件的父组件...... this.fire('msgFromOne', 123); } }); var ComponentTwo = sugar.Component.extend({ init: function (config) { this.Super('init', config, { view: '<SubComponent></SubComponent>', childs: { SubComponent: ComponentOne } }); }, // 该消息由 ComponentOne 发出 // 因为 ComponentTwo 是 ComponentOne 的父组件,所以能接收到冒泡消息 onMsgFromOne: function (msg) { console.log(msg.param); // 123 消息参数 console.log(msg.type); // 'fire' console.log(msg.count); // 1 消息被传递的次数 console.log(msg.from); // ComponentOne 实例,消息发送源 } }); var ComponentThree = sugar.Component.extend({ init: function (config) { this.Super('init', config, { view: '<SubComponent></SubComponent>', childs: { SubComponent: ComponentTwo } }); }, // 该消息由 ComponentOne 发出 // 因为 ComponentThree 是 ComponentTwo 的父组件,所以也能接收到冒泡消息 onMsgFromOne: function (msg) { console.log(msg.param); // 123 消息参数 console.log(msg.type); // 'fire' console.log(msg.count); // 2 消息被传递的次数 console.log(msg.from); // ComponentOne 实例,消息发送源 } });
广播通信也要求通信的组件之间是"父子关系",但广播通信与冒泡通信的消息流动机制相反,消息由父组件发出,每个子组件接收,并且消息会广播到到每一个子组件的子组件:
var ComponentOne = sugar.Component.extend({ init: function (config) { this.Super('init', config); }, // 该消息由 ComponentThree 发出 // 因为 ComponentOne 是 ComponentTwo 的子组件,所以也能接收到广播消息 onMsgFromThree: function (msg) { console.log(msg.param); // 456 console.log(msg.type); // 'broadcast' } }); var ComponentTwo = sugar.Component.extend({ init: function (config) { this.Super('init', config, { view: '<SubComponent></SubComponent>', childs: { SubComponent: ComponentOne } }); }, // 该消息由 ComponentThree 发出 // 因为 ComponentTwo 是 ComponentThree 的子组件,所以能接收到广播消息 onMsgFromThree: function (msg) { console.log(msg.param); // 456 } }); var ComponentThree = sugar.Component.extend({ init: function (config) { this.Super('init', config, { view: '<SubComponent></SubComponent>', childs: { SubComponent: ComponentTwo } }); }, afterRender: function () { // broadcast 会将消息发到所有子组件,以及每个子组件的所有子组件...... this.broadcast('msgFromThree', 456); } });
冒泡和广播通信都要求通信组件之间是父子关系,而一对一通信 notify 则可用于任意两个有关系或没关系组件之间的通信。通信的依据是组件创建时的名称(同一层级的组件的名称是不允许重复的)
var SubComponent = sugar.Component.extend({ init: function (config) { this.Super('init', config); }, // 从 ComponentB 发来的消息 onMsgToSubComponent: function (msg) { console.log(msg.param); // 456 } }); var ComponentA = sugar.Component.extend({ init: function (config) { config = this.cover(config, { target: document.body, view: '<Sub></Sub>', childs: { Sub: SubComponent } }); }, // 从 ComponentB 发来的消息 onMsgToComponentA: function (msg) { console.log(msg.param); // 123 } }); var compA = sugar.core.create('componentA', ComponentA); var ComponentB = sugar.Component.extend({ init: function (config) { this.Super('init', config); }, afterRender: function () { // 与 ComponentA 通信,'componentA' 是组件创建时的名称 this.notify('componentA', 'msgToComponentA', 123); // 也可以传入组件实例进行通信: // this.notify(compA, 'msgToComponentA', 123); // 与 ComponentA 的子组件 SubComponent 通信 // 由于是 ComponentA 的子组件,所以需要指定组件的路径层级,用 . 分割 this.notify('componentA.Sub', 'msgToComponentA', 123); // 也可以传实例进行通信: // this.notify(compA.getChild('Sub'), 'msgToComponentA', 123); } });
顾名思义,全局广播通信是向所有组件发送消息,这个方法只挂载在 sugar.core 实例上(sugar.core 实际上是一个只有组件系统而没有视图的顶级模块实例)。一个使用场景比如用户的登入和登出状态发生了改变,可以很方便的使用 globalCast 来通知所有组件,从而更新组件内部对于登入和登出的数据和信息。
var user = 'Kobe'; sugar.core.globalCast('userLogin', user); sugar.core.globalCast('userLogout', user);
上一篇:组件的嵌套
下一篇:完整 API