派送事件如何进行回调 (dispatchEvent)

子节点使用dispatchEvent派送事件,某一父节点收到后如何回调。也就是父节点响应派送事件后,如何传递信息给派发事件的子节点。求大神指点。

1赞

阅读理解:joy:

// CallbackEvent.js: 一个包含callback的自定义事件
var eventName = "CallbackEvent";
var CallbackEvent = cc.Class({
    extends: cc.Event.EventCustom,
    statics: {
        Name: eventName
    },
    properties: {
        callback: null
    },
    init(callback) {
        // 事件名
        this.type = eventName;
        // 开启事件冒泡
        this.bubbles = true;
        // 设置回调函数
        this.callback = callback;
    }
});
module.exports = CallbackEvent;

// Child.js: 子节点,新建一个CallbackEvent,设置回调,然后dispatch
var CallbackEvent = require('CallbackEvent');
cc.Class({
    extends: cc.Component,
    onLoad: function () {
        var event = new CallbackEvent();
        event.init(function(str) {
            cc.log(str);
        });
        this.node.dispatchEvent(event);
    }
});

// Father.js: 父节点,监听CallbackEvent,通过event.callback调用子节点传来的回调
var CallbackEvent = require('CallbackEvent');
cc.Class({
    extends: cc.Component,
    onLoad: function () {
        this.node.on(CallbackEvent.Name, function(event) {
           event.callback("Hello World!");
        });
    }
});
2赞

明白了,就是父节点截取事件后调用子节点创建事件时定义的方法,从而实现信息的传递。受教了,十分感谢~

将eventName设为statics,而不是作为一个参数放在init中,请问是有什么原因吗?这样无法同时使用多个实例。

cc.Event.EventCustom有一个type属性,可以理解为事件名称,在CallbackEvent的init里我赋值了的。父节点设置监听的时候,this.node.on的第一个参数必须等于事件的type才会响应事件。也就是说,父节点的脚本里面注册事件时,只需要事件的type,但不需要这个事件的实例。所以只需要一个静态的参数。如果不是静态的,那得写成这样:

// Father.js
onLoad() {
    // 只需要事件的type,却实例化一个了一个事件
    var event = new CallbackEvent();
    event.init();
    this.node.on(event.type, ...);
}

也可以不要CallbackEvent.Name(其实应该写成eventType、CallbackEvent.Type,跟引擎的命名习惯一致),直接写

this.node.on("CallbackEvent",...)

也能接收到事件。但是这样的话如果哪天你想改一下这个事件的名称(比如改为ChildCallbackEvent),那你就得找出所有使用使用这个事件的地方一一把名字都改了。

3赞

明白了,如果不写死type的话还是去设置event的type就可以了。
还想请教一下大神有没有从父节点向子节点派送事件的方法。

据我所知没有父节点向子节点的,我一般用全局事件。

// 在所有事件运行前new一个全局的EventTarget
window.GlobalEvent = new cc.EventTarget();
// Child.js
GlobalEvent.on("GlobalEvent", this.onGlobalEvent, this);
// Father.js
var globalEvent = new cc.Event.EventCustom();
globalEvent.type = "GlobalEvent";
GlobalEvent.dispatchEvent(globalEvent);

我使用这种方法时发现的缺点是,即使Child节点销毁了,GlobalEvent还是会响应Child注册的事件,有可能导致未知错误(比如如果Child.js的this.onGlobalEvent里有代码访问this.node就会出错)。我一般会在Child.js的onDestroy(){}里写

// Child.js
onDestroy() {
    GlobalEvent.off("GlobalEvent", this.onGlobalEvent, this);
}

如果哪位大神有更好的方法,请告诉我:grin:

1赞

使用系统的事件管理

> var _listener = cc.EventListener.create({
>             event: cc.EventListener.CUSTOM,
>             eventName: event_name,
>             callback: function (event) {
>                 // TODO
>             }
>         });
> cc.eventManager.addListener(_listener, nodeOrProity);// nodeOrProity是监听的 node如果node删除了,监听自动失效
1赞

谢谢!就是现在引擎组的大大们都推荐用on,不推荐用EventListener了。。

如果发送消息太频繁确实不推荐,就使用情况来看效率没啥影响。