简体   繁体   中英

Angular 4/5 Observable - How to update component template depending on observable property?

Ok I am still a newbie. I have successfully created a 'dashboard' component that has a left sidebar with links. On the right is where I have content/components displayed that I want to change dynamically depending on what link was clicked on the left sidebar (see bootstrap sample of what this dashboard looks like here, click on the toggle button to view the sidebar: https://blackrockdigital.github.io/startbootstrap-simple-sidebar/ ).

I have created a DashboardService that has a Subject and an Observable to allow for sibling component communication. This works great since I have a console.log() that shows this communication working (when I click on link on sidebar in SidebarComponent, I console.log() a value 'emitted' by the DashboardService that is being listened to by the SidebarComponent's sibling, DashboardSectionComponent).

The problem that I am having is that the template in DashboardSectionComponent loads the correct component section ONLY on initial load of page - once I click on a link on the side bar the content is blank and nothing is rendered.

Here is the service that allows the componenent communication:

import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
import { Observable } from 'rxjs/Observable';

@Injectable()
export class DashboardService {

    private selectedComponentAlias = new Subject<string>();

    constructor() {}

    setSelectedComponentAlias(alias: string) {
        this.selectedComponentAlias.next(alias);
    }

    getSelectedComponentAlias(): Observable<string> {
        return this.selectedComponentAlias.asObservable();
    }

}

Here is the SidebarComponent:

import { Component, OnInit } from '@angular/core';

import { DashboardService } from '../dashboard.service';

@Component({
    selector: 'app-sidebar',
    templateUrl: './sidebar.component.html',
    styleUrls: ['./sidebar.component.css']
})
export class SidebarComponent implements OnInit {

    constructor(private dashboardService: DashboardService) { }

    ngOnInit() {
    }

    onShowSection(event) {
        event.preventDefault();
        const componentAlias = event.target.getAttribute('data-componentAlias');
        this.dashboardService.setSelectedComponentAlias(componentAlias);
    }

}

here is the DashboardSectionComponent (the one that subscribes to the observable and I want to set property that controls the template views depending on the value that was caught)

import { Component, OnInit, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs/Subscription';

import { DashboardService } from '../dashboard.service';

@Component({
    selector: 'app-dashboard-section',
    templateUrl: './dashboard-section.component.html',
    styleUrls: ['./dashboard-section.component.css']
})
export class DashboardSectionComponent implements OnInit, OnDestroy {

    private subscrition: Subscription;
    selectedComponentAlias: string = 'user-profile';

    constructor(private dashboardService: DashboardService) {

    }

    ngOnInit() {
        this.subscrition = this.dashboardService.getSelectedComponentAlias()
            .subscribe((selectedComponentAlias: string) => {
                this.selectedComponentAlias = selectedComponentAlias;
                console.log('user clicked: ',this.selectedComponentAlias);
            });
    }

    ngOnDestroy() {
        this.subscrition.unsubscribe();
    }

}

Finally here is the template for DashboardSectionComponent which might have wrong syntax:

<div *ngIf="selectedComponentAlias == 'my-cards'">
    <app-cards></app-cards>
</div>

<div *ngIf="selectedComponentAlias == 'user-profile'">
    <app-user-profile></app-user-profile>
</div>

<div *ngIf="selectedComponentAlias == 'user-settings'">
    <app-user-settings></app-user-settings>
</div>

Again, this works great (selectedComponentAlias is 'user-profile' on page load by default). But it goes blank after I click on a Sidebar link....

Thanks.

这很容易-就像@RandyCasburn指出的那样,这是使路由正常工作的问题。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM