EventEmitter не перехватывает событие - PullRequest
1 голос
/ 18 октября 2019

Я пытался заставить свой компонент панели инструментов передавать данные другому компоненту (dat.gui -> three.js). Я предполагал, что понадобится создать выходной излучатель, и он работает, но он как-то не работает. В этих компонентах нет фактического HTML-кода.

Все, что мне нужно сделать, это отправить событие с интерфейсом, содержащим данные (в настоящее время это просто boolean, но оно будет расширено позже). Мой проект также на GitHub, если это будет яснее. Я читал о различных способах работы с Angular, но все еще довольно нов. В связи с этим, если я допустил глупую ошибку, пожалуйста, скажите мне, потому что я понятия не имею, что я делаю здесь неправильно.

https://github.com/GrimZero/ConfiguratorAngular

урегулирование .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();
  }
}

Ответы [ 3 ]

0 голосов
/ 18 октября 2019

Похоже, вы неправильно объявили свое событие:

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);
    }
}
0 голосов
/ 18 октября 2019

Во-первых, Output генерирует событие от дочернего к родительскому компоненту, и в вашем коде нет никаких родительских-дочерних отношений в вашем коде (в этом случае вы можете воспользоваться услугами). Но для обработки событий с использованием родительских и дочерних компонентов вы должны внести следующие изменения:

В 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 -->
0 голосов
/ 18 октября 2019

Вы можете использовать только @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';

Надеюсь, это поможет вам!

...