Fondamentalmente voglio creare un componente di dialogo personalizzato che posso utilizzare da qualsiasi punto della mia app Angular2 indipendentemente da dove si trova il componente di utilizzo nell'albero delle applicazioni. Per semplicità, chiamiamo questo mio componente SayHello.Come rendere un componente universalmente accessibile in Angular2
Si consideri il seguente albero di applicazione:
Quindi diciamo che voglio SomeComponent.level3.component per richiamare la finestra di dialogo in SayHello.component.
In Angular 1.x, inserisco RootScope in un controller e accendo una finestra di dialogo in questo modo. Ora capisco (più o meno) che per Angular2 è possibile creare degli eventi a bolla (con gli emettitori di eventi) nell'albero dei componenti, ma sembra noioso bombardare un evento fino in fondo da SomeComponent.level3.componente sull'albero e giù fino a SayHello .componente.
Quindi ho pensato di creare un servizio SayHello che avrei iniettato ovunque volessi illuminare il mio dialogo. Ecco uno schizzo del codice che ho formulato.
myApp.component.ts
import {SayHelloComponent} from "<<folder>>/sayHello.component";
import {BunchOfComponents} from "<<folder>>/bunchOfComponents";
@Component({
directives: [SayHelloComponent],
selector: "my-app",
templateUrl: `<bunch-of-components>Within this component exists
SomeComponent.level3.component </bunch-of-components>
<say-hello showdialog="{{showDialog}}" message="{{message}}">
</say-hello>`
})
export class myAppComponent {
showDialog = false;
message = "";
constructor(private sayHelloService: SayHelloService) {
this.showDialog = sayHelloService.showDialog;
this.message = sayHelloService.message;
}
}
SayHelloService.ts
import {Injectable} from 'angular2/core';
@Injectable()
export class SayHelloService {
public showDialog: boolean = false;
public message: string ="";
constructor() {
}
}
SayHello.component.ts
import {Component} from "angular2/core";
import {SayHelloService} from "<<folder>>/SayHelloService";
@Component({
directives: [],
selector: "say-hello",
template: "[do hello component]"
})
export class SayHelloComponent {
@Input() showdialog: boolean;
@Input() message: string;
constructor(private sayHelloService: SayHelloService) {
}
//This idea here is to detect change in showDialog
//If true then do an alert with the message
ngOnChanges(changes: { [propName: string]: SimpleChange }) {
var obj = changes["showdialog"];
if (obj !== null) {
if (changes["showdialog"].currentValue === true) {
alert(this.message);
this.sayHelloService.showDialog = false;
}
};
}
}
SomeComponent.level3.component
import {Component} from "angular2/core";
import {SayHelloService} from "<<folder>>/SayelloService";
@Component({
directives: [],
selector: "some-component",
template: "<button (click)='doHello()'>Do say hello</button>"
})
export class PageContactUsComponent {
constructor(private sayHelloService: SayHelloService) {
}
doHello(): void {
this.sayHelloService.message = "Hello world";
this.sayHelloService.showDialog = true;
}
}
appBoot.ts
import {bootstrap} from "angular2/platform/browser";
import {MyAppComponent} from "<<folder>/MyAppComponent";
import {SayHelloService} from "<<folder>>/SayHelloService";
bootstrap(MyAppComponent, [
SayHelloService
]);
Inutile dire che questo non funziona. Non ricevo errori, ma il SayHello.component non rileva alcun cambiamento nel valore di 'showdialog' ... quindi non succede nulla. Qualsiasi idea su come farlo correttamente sarebbe molto apprezzata.
Anziché (o forse in aggiunta a) pubblicare tutti questi frammenti di codice singolarmente, avente una plunkr con tutte queste parti di lavoro insieme renderebbero molto più facile per me/noi giocare con la tua implementazione e mostrarti cosa deve cambiare – drewmoore
#drewmoore, una buona idea funzionerà in plunkr. #pixelbits, sì, questa è la mia strategia, ma sto facendo qualcosa di sbagliato. – brando
FYI, gli eventi personalizzati (dall'emettitore di eventi) non possono essere fatti bollire (solo gli eventi DOM possono). – pixelbits