Three.js EventDispatcher可以用于在类之间进行通信吗?

时间:2018-10-07 15:17:10

标签: javascript ecmascript-6 three.js assign event-dispatching

核心问题

在一个支持EventDispatcher的类上发出的事件不会被另一个支持EventDispatcher的类拾取。

如何使通信在整个应用程序范围内进行,以便我可以传递消息?

目前看来,它仅支持将消息传递到其自己的类。

背景

我正在使用此样板,它提供了three.js和es6:

https://github.com/paulmg/ThreeJS-Webpack-ES6-Boilerplate

我已经手动更新了软件包以使用three.js r97。

我正在查看EventDispatcher类,并且我认为这是让我在保持解耦的同时在系统周围传递消息的一种干净方法。例如,我有一些监视复选框的HTML UI。

简单介绍一下核心示例,我有一个interact.js:

import {EventDispatcher} from 'three';

// Manages all input interactions
export default class Interaction {
  constructor() {
    // Add event dispatcher support
    Object.assign( this, EventDispatcher.prototype );

    // setup the trigger for the event
    let outer = this;
    $("#" + Config.uiElements.boxOpenStateId).change(function() {
      console.log("event emitting");
      outer.dispatchEvent( { type: 'boxOpenStateToggled', message: { isChecked: "example" } } );
      console.log("event emitted");
    });

    // setup a event listener
    this.addEventListener( 'boxOpenStateToggled', function ( event ) {
      console.log("event caught in Interaction.js", event);
    });
  }
}

我有boxmanager.js(已精简到核心部分):

import {EventDispatcher} from 'three';

export default class BoxManager {
    constructor() {
        // Add event dispatcher support
        Object.assign( this, EventDispatcher.prototype );
    }

    setupBoxes(manager) {
        console.log("adding event listener on BoxManager.js");
        this.addEventListener( 'boxOpenStateToggled', function ( event ) {
            console.log("event caught by BoxManager.js", event);        
        } );
    }
}

当我在boxOpenStateToggled上触发Interaction事件时,BoxManager事件监听器不会捕获它。

我得到一个这样的控制台日志:

adding event listener on BoxManager.js
adding event listener on Interaction.js

(I trigger the event)

event emitting
event caught in Interaction.js {type: "boxOpenStateToggled", message: {…}, target: Interaction}
event emitted

我在这里期望看到的也是“ BoxManager中捕获的事件”-它是系统范围的事件分派器吗?还是只能按类在内部调度事件?

显示我的工作

我不确定这是否是我使用它的方式,所以我尝试了:

  • 在类上使用extends关键字来提供EventDispatcher功能,并且它只能在类中使用。

  • 最初使用的是.call版本,该版本在three.js的早期版本中。

我找不到任何真正的讨论或使用EventDispatcher的示例,也看不到它甚至在库中的使用位置。

我误解了它的目的吗?我用错了吗?

1 个答案:

答案 0 :(得分:1)

您可以考虑这样做:

const myEventBus = new THREE.EventDispatcher()

const foo = new Foo(myEventBus)
const bar = new Bar(myEventBus)

如果要避免将实例传递给这样的对象或创建工厂,则可以执行以下操作:

//Events.js
const Events = new THREE.EventDispatcher()
export default Events

然后:

//Foo.js
import Events from 'common/Events'
import {BOX_OPEN} from 'Bar'
export default class Foo {
  constructor(){
    Events.addEventListener( BOX_OPEN, this.onBoxOpen);
  }
}

发送

//Bar.js

export const BOX_OPEN = 'box_open'

export default class Bar {
  constructor(){
    $("#" + Config.uiElements.boxOpenStateId).change(this.onChange);
  }
  onChange = () => {
     console.log("event emitting");
     Events.dispatchEvent({ type: BOX_OPEN, message: { isChecked: "example" } });
     console.log("event emitted");
  }
}