Skip to content

Message

TANG edited this page Dec 14, 2016 · 8 revisions

组件的消息通信

组件通信对解决复杂的交互也有很大的用处,sugar 支持冒泡通信(fire)、广播通信(broadcast)、一对一通信(notify) 和全局广播通信(globalCast) 4 种通信方式,这四种通信方式能解决大部分的组件通信需求。

消息的接收统一在组件内部用 on + 消息名称首字母大写的函数方法来接收(如:onMessage)。

冒泡通信 fire

冒泡通信要求通信的组件之间是“父子关系”,消息由子组件发出,父组件接收,并且消息会“冒泡”到父组件的父组件:

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 实例,消息发送源
	}
});

广播通信 broadcast

广播通信也要求通信的组件之间是“父子关系”,但广播通信与冒泡通信的消息流动机制相反,消息由父组件发出,每个子组件接收,并且消息会广播到到每一个子组件的子组件:

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

冒泡和广播通信都要求通信组件之间是父子关系,而一对一通信 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);
	}
});

全局广播通信 globalCast

顾名思义,全局广播通信是向所有组件发送消息,这个方法只挂载在 sugar.core 实例上(sugar.core 实际上是一个只有组件系统而没有视图的顶级模块实例)。一个使用场景比如用户的登入和登出状态发生了改变,可以很方便的使用 globalCast 来通知所有组件,从而更新组件内部对于登入和登出的数据和信息。

var user = 'Kobe';
sugar.core.globalCast('userLogin', user);

sugar.core.globalCast('userLogout', user);

上一篇:组件的嵌套

下一篇:完整 API