【问题标题】:Angular 4/5 Observable - How to update component template depending on observable property?Angular 4/5 Observable - 如何根据可观察属性更新组件模板?
【发布时间】:2018-04-06 23:40:40
【问题描述】:

好吧,我还是个新手。我已经成功创建了一个“仪表板”组件,它有一个带有链接的左侧边栏。右侧是显示内容/组件的位置,我希望根据在左侧边栏上单击的链接动态更改这些内容/组件(请参阅此处仪表板外观的引导示例,单击切换按钮以查看侧边栏:@ 987654321@).

我创建了一个具有 Subject 和 Observable 的 DashboardService 以允许同级组件通信。这很好用,因为我有一个显示此通信工作的 console.log()(当我单击 SidebarComponent 中侧边栏上的链接时,我 console.log() 是由 SidebarComponent 监听的 DashboardService “发出”的值兄弟,DashboardSectionComponent)。

我遇到的问题是 DashboardSectionComponent 中的模板仅在页面初始加载时加载正确的组件部分 - 一旦我单击侧栏上的链接,内容为空白并且没有呈现任何内容。

这是允许组件通信的服务:

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();
    }

}

这里是 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);
    }

}

这里是 DashboardSectionComponent(订阅 observable 的组件,我想根据捕获的值设置控制模板视图的属性)

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();
    }

}

最后是 DashboardSectionComponent 的模板,它可能有错误的语法:

<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>

同样,这很好用(默认情况下,在页面加载时,selectedComponentAlias 是“用户配置文件”)。但是点击侧边栏链接后它会变成空白......

谢谢。

【问题讨论】:

  • 我真的很讨厌成为坏消息的承担者,但你的做法有点不对劲。您可以完成这项工作,而且不会太难,但您的方法不会很好地扩展。仅查看右侧的内容部分,您需要三个独立的组件(my-cards、user-profile、user-settings)。您应该研究使用路由和&lt;router-outlet&gt; 来适当地解决此问题。
  • 我同意@RandyCasburn。另外,只是关于 observables 和 Angular 的提示——我不会在组件中保存 selectedComponentAlias(或任何其他从 Observable 发出的值),而是使用 async 管道并让 Angular 处理订阅。
  • 输出是什么,console.log('user clicked: ',this.selectedComponentAlias); ?
  • @Luillyfe 正确的字符串显示在日志中。
  • @RandyCasburn 你能提供更多意见吗?我是新手-我有路线-但是您能解释一下拥有这三个独立组件有什么问题吗?例如,我计划在其他地方重用 my-cards 组件......

标签: javascript angular frontend observable single-page-application


【解决方案1】:

这很简单——就像@RandyCasburn 指出的那样,这是让路由正常工作的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-06
    • 1970-01-01
    • 2018-01-02
    • 2016-09-19
    • 1970-01-01
    相关资源
    最近更新 更多