three.js EventDispatcher 可以用于 类 之间的通信吗?
can the three.js EventDispatcher be used to communicate between classes?
核心问题
在一个支持 EventDispatcher 的 class 上发出的事件不会被另一个支持 EventDispatcher 的 class 拾取。
如何让通信在整个应用程序范围内正常工作,以便我可以传递消息?
目前好像只支持给自己传消息class.
背景
我正在使用这个样板,它给了我 three.js 和 es6:
https://github.com/paulmg/ThreeJS-Webpack-ES6-Boilerplate
我已手动更新包以使用 three.js r97。
我正在查看 EventDispatcher class,我认为这是一种干净的方式,可以让我在系统周围传递消息,同时保持解耦。例如,我有一些 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
我在这里期待的是 "event caught in BoxManager" - 它是系统范围的事件调度程序吗?或者它只能在每个 class 的基础上在内部调度事件?
展示我的作品
我不确定这是否是我使用它的方式所以我尝试了:
在 class 上使用 extends
关键字来提供 EventDispatcher
功能并且它有效但仅在 class.
最初使用 .call
版本,它是 three.js 的早期版本。
我找不到任何关于使用 EventDispatcher 的真正讨论或示例,甚至看不到它在库中的使用位置。
我是不是误解了它的用途?我用错了吗?
你可以考虑这样做:
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");
}
}
核心问题
在一个支持 EventDispatcher 的 class 上发出的事件不会被另一个支持 EventDispatcher 的 class 拾取。
如何让通信在整个应用程序范围内正常工作,以便我可以传递消息?
目前好像只支持给自己传消息class.
背景
我正在使用这个样板,它给了我 three.js 和 es6:
https://github.com/paulmg/ThreeJS-Webpack-ES6-Boilerplate
我已手动更新包以使用 three.js r97。
我正在查看 EventDispatcher class,我认为这是一种干净的方式,可以让我在系统周围传递消息,同时保持解耦。例如,我有一些 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
我在这里期待的是 "event caught in BoxManager" - 它是系统范围的事件调度程序吗?或者它只能在每个 class 的基础上在内部调度事件?
展示我的作品
我不确定这是否是我使用它的方式所以我尝试了:
在 class 上使用
extends
关键字来提供EventDispatcher
功能并且它有效但仅在 class.最初使用
.call
版本,它是 three.js 的早期版本。
我找不到任何关于使用 EventDispatcher 的真正讨论或示例,甚至看不到它在库中的使用位置。
我是不是误解了它的用途?我用错了吗?
你可以考虑这样做:
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");
}
}