首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >EventEmitter未捕获事件

EventEmitter未捕获事件
EN

Stack Overflow用户
提问于 2019-10-18 15:17:41
回答 3查看 583关注 0票数 1

我一直在尝试让我的工具栏组件向另一个组件(dat.gui -> three.js)发送数据。我假设需要的是创建一个输出发射器,这是有效的,但它不是以某种方式工作。在这些组件中没有实际的html代码。

我需要做的就是用保存数据的接口发出事件(目前只是一个boolean,稍后会扩展)。我的项目也在github上,如果这会更清楚的话。我一直在阅读各种使用Angular的方法,但仍然是个新手。在这方面,如果我犯了一个愚蠢的错误,请告诉我,因为我不知道我在这里做错了什么。

https://github.com/GrimZero/ConfiguratorAngular

settngs.service.ts

代码语言:javascript
复制
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class SettingsService {

  $dataChange: Subject<any> = new Subject<any>();
}

toolbar.component.ts

代码语言:javascript
复制
import { GUI } from './../../../node_modules/three/examples/jsm/libs/dat.gui.module';
import { Settings } from '../settings';
import { SettingsService } from '../settings.service';

@Component({
  selector: 'app-toolbar',
  templateUrl: './toolbar.component.html',
  styleUrls: ['../app.component.css']

})
export class ToolbarComponent implements OnInit {
  settingsData: Settings;

  constructor(private service: SettingsService) {
    this.settingsData = this.defineSettings({ TimeNight: false });
  }

  defineSettings(config: Settings) {
    const settings = { TimeNight: true };

    if (config.TimeNight) {
      settings.TimeNight = config.TimeNight;
    }

    return settings;
  }

  onChange() {
    this.service.$dataChange.next(this.settingsData);
    console.log('emitted');
  }

  ngOnInit() {
    const gui = new GUI();
    gui.add(this.settingsData, 'TimeNight').onChange(() => {
      this.onChange();
    });
  }
}

threejs.component.ts

代码语言:javascript
复制
import { Component, OnInit } from '@angular/core';
import { Material } from '../material.js';
import { TimeOfDay } from '../time-of-day.js';
import { Threejscontroller } from '../threejscontroller.js';
import { SettingsService } from '../settings.service.js';


@Component({
  selector: 'app-threejs',
  templateUrl: './threejs.component.html',
  styleUrls: ['../app.component.css']
})
export class ThreejsComponent implements OnInit {
  threejs: Threejscontroller;

  constructor(private service: SettingsService) { }

  updateWebGL = (settingsData: any) => {
    console.log('recieved message');

    if (!settingsData.TimeNight) {
      new TimeOfDay().SetTimeDay(this.threejs.scene);
    } else {
      new TimeOfDay().SetTimeDusk(this.threejs.scene);
    }
  }

  ngOnInit() {
    this.service.$dataChange.subscribe((value: any) => {
      console.log(value);
      // this.updateWebGL(value);
    });

    this.threejs = new Threejscontroller();
    this.threejs.update();
  }
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-10-18 15:27:59

您只能使用@Output从子组件向父组件传递数据。我认为你的方法是错误的

因此,您必须通过使用服务来实现:

定义了一个类似于bellow的服务

代码语言:javascript
复制
@Injectable()
export class MyService {
    $dataChange: Subject<any> = new Subject<any>();
}

确保将其添加到您的app.module.ts

代码语言:javascript
复制
@NgModule({    
    providers: [
        MyService
    ]
})

并将其注入到ThreejsComponent中并像bellow一样使用它

代码语言:javascript
复制
export class ThreejsComponent implements OnInit {
  threejs: Threejscontroller;

  constructor(private myService: MyService) { }

  UpdateWebGL = (settingsData: Settings) => {
    console.log('recieved message');

    if (!settingsData.TimeNight) {
      new TimeOfDay().SetTimeDay(this.threejs.scene);
    } else {
      new TimeOfDay().SetTimeDusk(this.threejs.scene);
    }
  }

  ngOnInit() {
    this.threejs = new Threejscontroller();
    this.threejs.update();

    this.myService.$dataChange.subscribe((value: any) => {
            this.UpdateWebGL(value);
        });
  }
}

ToolbarComponent使用中,如下图所示:

代码语言:javascript
复制
export class ToolbarComponent implements OnInit {
  settingsData: Settings;

  @Output() event: EventEmitter<Settings> = new EventEmitter<Settings>();

  constructor(private myService: MyService) {
    this.settingsData = this.defineSettings({ TimeNight: false });
  }

  defineSettings(config: Settings) {
    const settings = { TimeNight: true };

    if (config.TimeNight) {
      settings.TimeNight = config.TimeNight;
    }

    return settings;
  }

  onChange() {
    this.myService.$dataChange.next(this.settingsData);
    console.log("emitted");

  }

  ngOnInit() {
    const gui = new GUI();
    gui.add(this.settingsData, 'TimeNight').onChange(() => {
      this.onChange();
    });
  }
}

我检查了你的git代码,与你的导入问题请更改导入的ThreejsComponent

代码语言:javascript
复制
import { SettingsService } from '../settings.service.js'; 

代码语言:javascript
复制
import { SettingsService } from '../settings.service';

希望这篇文章能对你有所帮助!

票数 0
EN

Stack Overflow用户

发布于 2019-10-18 15:31:16

看起来你错误地声明了你的事件:

代码语言:javascript
复制
export class ToolbarComponent implements OnInit {
  settingsData: Settings;

  @Output() change: EventEmitter<Settings> = new EventEmitter<Settings>();


  onClick(){
    this.change.emit(this.settingsData);
  }

然后在app-threejs组件中处理(change)事件:

代码语言:javascript
复制
<app-threejs (change)="hello($event)"></app-threejs>


export class ThreejsComponent implements OnInit {
    hello(event:any) {
        console.log(event);
    }
}
票数 0
EN

Stack Overflow用户

发布于 2019-10-18 15:41:10

首先,输出从子组件到父组件发出一个事件,并且在您的代码中没有父子关系(在这种情况下,您可以使用服务)。但是对于使用父子组件处理事件,您应该进行以下更改。

app.component.html中,您必须只包含the组件。

代码语言:javascript
复制
<app-threejs (event)='UpdateWebGL($event)'><app-threejs>

threejs.component.html中添加工具栏,

代码语言:javascript
复制
<app-toolbar><app-toolbar> <!-- when the emit function get called to looks for the parent component from here -->
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58445768

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档