EventEmitter 没有捕捉到事件

EventEmitter not catching event

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

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

https://github.com/GrimZero/ConfiguratorAngular

settngs.service.ts

import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';

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

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

toolbar.component.ts

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

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();
  }
}

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

所以你必须通过使用服务来实现它:

定义如下服务

@Injectable()
export class MyService {
    $dataChange: Subject<any> = new Subject<any>();
}

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

@NgModule({    
    providers: [
        MyService
    ]
})

并将其注入 ThreejsComponent 并像下面那样使用它

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 中使用如下所示:

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

的导入
import { SettingsService } from '../settings.service.js'; 

import { SettingsService } from '../settings.service';

希望对您有所帮助!

您似乎错误地声明了您的活动:

export class ToolbarComponent implements OnInit {
  settingsData: Settings;

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


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

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

<app-threejs (change)="hello($event)"></app-threejs>


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

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

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

<app-threejs (event)='UpdateWebGL($event)'><app-threejs>

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

<app-toolbar><app-toolbar> <!-- when the emit function get called to looks for the parent component from here -->