【问题标题】:can the three.js EventDispatcher be used to communicate between classes?three.js 的 EventDispatcher 可以用于类之间的通信吗?
【发布时间】:2018-10-07 15:17:10
【问题描述】:

核心问题

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

如何让通信在整个应用程序范围内正常工作,以便我可以传递消息?

目前它似乎只支持将消息传递给自己的类。

背景

我正在使用这个样板,它给了我三个.js 和 es6:

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

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

我正在查看 EventDispatcher 类,我认为这是一种在系统中传递消息同时保持解耦的干净方式。例如,我有一些 HTML UI 可以查看复选框。

精简到核心示例,我有interaction.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);        
        } );
    }
}

当我在Interaction 上触发boxOpenStateToggled 事件时,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 功能,它只在类内有效。

  • 最初使用的是早前的three.js 版本中的.call 版本。

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

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

【问题讨论】:

  • 我不太明白这个问题。 EventDispatcher 这样做 - 调度事件。三人的大部分课程都扩展了这个课程。您可以在三个之外使用它,它非常通用。所以可以肯定,答案是肯定的。但是您的问题更多是关于语言和模式的语义。在这种情况下,我不太清楚这是什么,我可能会重新访问addyosmani.com/resources/essentialjsdesignpatterns/book
  • @pailhead 我的困惑是我已经扩展了两个类来支持事件调度程序,当我在一个上调度一个事件时,即使我有一个处理程序,它也不会被另一个接收到。
  • @pailhead 我已经更新了我的问题,希望能更清楚地说明我的问题,感谢您到目前为止的关注
  • 好吧,我认为这不是EventDispatcher 的问题,而是你如何使用 JS。我对此有点困惑,必须深入挖掘,但你对原型和Object.assign 所做的事情似乎很奇怪。我不认为你在分派和收听同一个对象。
  • `它是一个系统范围的事件调度器吗?或者它只能在每个类的基础上在内部调度事件?` 不,不是。您可以通过遵循某种模式自己使其全球化。您的另一个对象不知道第一个对象的事件。

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


【解决方案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");
  }
}

【讨论】:

  • 我同意这似乎是使用它的一种方式,但它让我感到困惑,因为它没有遵循示例。我正在做的奇怪的原型是setup from the three.js docs。似乎如果它只能在该单个对象之间传递消息,那么它不是很有用。感觉我们都缺少一些东西,否则我不知道为什么它被实现到 three.js 中并以这种方式记录。
  • 请注意,该示例使用prototype,您将其分配给this
  • 在你的情况下Object.assign(Interaction.prototype, EventDispatcher.prototype)
  • 感谢您一直支持我,这准确地解释了我期望如何使用它,我想我只是需要更多的 JavaScript 知识来理解我在看什么 :)
  • 不用担心。我对原型的东西很困惑,但我什至不确定它是否会破坏它。但这不是问题。
猜你喜欢
  • 2016-10-29
  • 2014-09-16
  • 2017-03-02
  • 1970-01-01
  • 1970-01-01
  • 2023-03-17
  • 1970-01-01
  • 2015-06-13
  • 1970-01-01
相关资源
最近更新 更多