我一直在尝试让我的工具栏组件向另一个组件(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();
}
}发布于 2019-10-18 15:27:59
您只能使用@Output从子组件向父组件传递数据。我认为你的方法是错误的
因此,您必须通过使用服务来实现:
定义了一个类似于bellow的服务
@Injectable()
export class MyService {
$dataChange: Subject<any> = new Subject<any>();
}确保将其添加到您的app.module.ts中
@NgModule({
providers: [
MyService
]
})并将其注入到ThreejsComponent中并像bellow一样使用它
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';希望这篇文章能对你有所帮助!
发布于 2019-10-18 15:31:16
看起来你错误地声明了你的事件:
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);
}
}发布于 2019-10-18 15:41:10
首先,输出从子组件到父组件发出一个事件,并且在您的代码中没有父子关系(在这种情况下,您可以使用服务)。但是对于使用父子组件处理事件,您应该进行以下更改。
在app.component.html中,您必须只包含the组件。
<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 -->https://stackoverflow.com/questions/58445768
复制相似问题