Po prostu chcę utworzyć niestandardowy komponent okna dialogowego, który mogę wykorzystać z dowolnego miejsca w mojej aplikacji Angular2, bez względu na to, gdzie w drzewie aplikacji jest używany składnik. Dla uproszczenia, nazwijmy to moim Komponentem SayHello.Jak sprawić, by komponent był powszechnie dostępny w Angular2
Rozważmy następujący drzewie aplikacji:
Więc powiedzmy chcę SomeComponent.level3.component, aby wywołać okno w SayHello.component.
W Angular 1.x wprowadziłbym RootScope do kontrolera i uruchomiłam okno dialogowe w ten sposób. Teraz rozumiem (mniej więcej), że dla Angular2 można dymić zdarzenia (z emiterami zdarzeń) w górę drzewa komponentów, ale nudne wydaje się wydarzenie z systemu SomeComponent.level3.component w górę drzewa i w dół do SayHello .składnik.
Więc pomyślałem, że stworzę usługę SayHello, którą będę wstrzykiwać wszędzie, gdzie chcę oświetlić mój dialog. Oto szkic kodu, który sformułowałem.
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
]);
trzeba dodawać, że to nie działa. Nie dostaję żadnych błędów, ale SayHello.component nie wykrywa żadnej zmiany wartości "showdialog" ... więc nic się nie dzieje. Wszelkie sugestie, jak to zrobić właściwie, będą mile widziane.
Zamiast (albo oprócz) wysyłania wszystkie te fragmenty kodu indywidualnie o plunkr z wszystkie te działające razem części ułatwiłyby mi/nam zabawę z twoją implementacją i pokazałoby ci, co trzeba zmienić – drewmoore
#drewmoore, dobry pomysł będzie działał w plunkr. #pixelbits, tak to jest moja strategia, ale robię coś złego. – brando
FYI, zdarzenia niestandardowe (według emitera zdarzeń) nie mogą być bąbelkowane (tylko zdarzenia DOM mogą). – pixelbits