2016-06-25 9 views
11

Mam problem z subskrypcją obserwowalnego nie wyzwalania.Angular 2 obserwowalna subskrypcja nie wyzwala

Mam układ za pomocą dyrektywy układ nav strona wygląda tak:

<md-sidenav-layout class="nav-bar"> 


    <md-sidenav #start> 
     <nav> 
      <a [routerLink]="['/home']">Home</a> 
     </nav> 
     <button md-button (click)="start.close()">Close</button> 
    </md-sidenav> 

    <router-outlet></router-outlet> 

</md-sidenav-layout> 

Co muszę zrobić, to otworzyć nav bok od składnika, że ​​router-wylot jest wyświetlanie.

Jeden taki element może wyglądać następująco:

@Component({ 

    providers: [SidenavService, MdIconRegistry], 
    directives: [MdIcon], 
    templateUrl: `<md-icon (click)="toggleSidenav()">menu</md-icon>`, 
    styleUrls: ["./home.component.scss"] 
}) 

export class Home { 

    myColor: string; 

    constructor(private sidenavService: SidenavService) { 
     this.myColor = "primary"; 

     this.sidenavService.getSidenavObs().subscribe(state => {console.log("state change")}); 
    } 


    toggleSidenav() { 

     this.sidenavService.toggleSidenav("open"); 
    } 

} 

Stworzyłem usługę, która zwraca się zaobserwować tak:

@Injectable() 
export class SidenavService { 

    private toggle = new Subject<string>(); 
    private toggleObs = this.toggle.asObservable(); 

    getSidenavObs() { 
     return this.toggleObs; 
    } 

    toggleSidenav(state: string) { 
     this.toggle.next(state); 
    } 

} 

Wreszcie kod dla klasy nadrzędnej (który należy z układ nawigacji bocznej HTML):

@Component({ 
    providers: [MdSidenav, SidenavService], 
    directives: [ROUTER_DIRECTIVES, MD_SIDENAV_DIRECTIVES, MD_BUTTON_DIRECTIVES], 
    selector: "app", 
    templateUrl: "app.html", 
    styleUrls: ["./app.scss"], 
}) 

export class App { 

    subscription: Subscription; 

    constructor(private sidenavService: SidenavService, private sidenav: MdSidenav) { 
    this.subscription = sidenavService.getSidenavObs().subscribe(status => { 
     console.log("state change"); 
     sidenav.open(); 
    }, error => { 
     console.log(error); 
    },() => { 
     console.log("completed"); 
    }); 
    } 
} 

Teraz mój problem polega na tym, że subskrypcja w Składnik aplikacji nie uruchamia jednak subskrypcji w elemencie Macierzystym (czyli tym, co wyświetla ekran routera), zgodnie z oczekiwaniami.

Czy tu czegoś brakuje?

Śledziłem ten przewodnik: https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service

Odpowiedz

49

tej samej instancji usługa nie jest współdzielona przez swoją aplikację i Spraw komponentów ponieważ zostały wymienione SidenavService jako dostawca dla obu stron.

Po zdefiniowaniu dostawcy usług w pozycji providers dekoratora komponentów usługa ta jest dostępna dla tego komponentu i wszystkich jego elementów podrzędnych jako singleton, co oznacza, że ​​zostanie użyte to samo wystąpienie usługi.

Jeśli przedefiniujesz dostawcę w elemencie podrzędnym, utworzy on nową instancję usługi i nie będzie już udostępniać tej samej instancji usługi, co jej element nadrzędny/element nadrzędny.

Jeśli używasz SidenavService zarówno w App, jak iw komponentach Home i potrzebujesz tego samego wystąpienia, powinieneś je podać tylko w komponencie App i usunąć go z wpisu Home w domenie providers.

Aby uzyskać więcej informacji na DI, mają czytać z poniższych linków: https://angular.io/docs/ts/latest/guide/dependency-injection.html https://angular.io/docs/ts/latest/guide/hierarchical-dependency-injection.html

+0

Dzięki wielkie! To rozwiązało mój problem. – mda144

+1

Dzięki Michael! – Leibniz

+0

Dzięki Michael !!. Uratowałeś mnie – bews99