当具有Observable Subject的共享服务中的其他组件更新时,一个组件未获得更新

时间:2018-02-15 12:34:36

标签: angular

我有2个组件, ProfileComponent AvatarComponent ,它们之间没有直接关系

配置文件组件在用户模块( user.module.ts )下使用,头像组件正在主模块中使用( app.module.ts )用户全名和右侧的个人资料图片。

我的要求是每当用户编辑他/她的个人资料(名字或姓氏)并点击保存按钮。比头像还更新了新的名字和姓氏

我已遵循此Component Communication approach from Angular Documentation

但我的问题是化身永远不会被更新,甚至没有从 avatar.component.ts

调用构造函数

角度版 4.3.4

以下是相关代码

Profile.component.ts

import { Component } from '@angular/core';
import { UserService } from '../user.service';

@Component({
    selector: 'app-profile',
    templateUrl: './profile.component.html'
})
export class ProfileComponent implements OnInit {

    constructor(private userService: UserService) { }

    announce() {
        console.log('announce called: ');
        let username = 'alpha beta';
        this.userService.announceUser(username);
    }
    // when click on save button on edit profile button
    updateProfile(userProfile) {
        this.userService.updateUserDetail(userProfile).subscribe(
            (data: any) => {
                this.announce();
            }
        );
    }
}

avatar.component.ts

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

import { UserService } from '../../../user/user.service';

@Component({
    selector: 'app-avatar',
    templateUrl: `<div>
    <img #avatar [title]="fullName" alt="profile-picture">
    <span>{{fullName}}</span>
    </div>`
})
export class AvatarComponent implements OnDestroy {
    fullName: string;
    subscription: Subscription;
    constructor(private userService: UserService) {
        this.getAvatar();
        this.subscription = userService.missionAnnounced$.subscribe(
            username => {
                console.log('subscribe it in constructor'); //never being called
                this.fullName = username;
            });
    }

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

    getAvatar() {
        this.userService.getUserDetail().subscribe(
            (data) => {
                this.fullName = `${data.firstName} ${data.lastName}`;
                this.userService.getProfilePicture().subscribe(
                    (image) => {
                        this.image.nativeElement.src = window.URL.createObjectURL(image);
                    }
                );
            }
        );
    }
}

user.service.js

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import 'rxjs/add/operator/map';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';

@Injectable()
export class UserService {

private missionAnnounceUsername = new Subject<string>();
missionAnnounced$ = this.missionAnnounceUsername.asObservable();
constructor(private httpClient: HttpClient) { }

announceUser(user: string) {
    console.log('announceUser: ', user);
    this.missionAnnounceUsername.next(user);
}

getUserDetail() {
    return this.httpClient.get(`/user/profile`).map((res) => res.item);
}

updateUserDetail(data) {
    return this.httpClient.put(`/user/profile`, data);
}

}

1 个答案:

答案 0 :(得分:0)

找到this issue

的解决方案

“不要两次注册任何提供者,因为这会创建两个独立的实例。”

我在主模块 app.module.ts 中注册了 UserService ,但它应该在 avatar.component.ts的父组件的提供程序元数据中 layout.component.ts

  • app.module.ts 提供商元数据中删除了UserService
  • layout.component.ts 提供商元数据中添加UserService

在layout.component.html

中使用<app-avatar>

现在一切正常。