Angular2 - 不同级别的组件之间的持久服务

时间:2016-11-16 21:54:07

标签: angular angular2-routing angular2-template angular2-forms angular2-services

我大部分时间都在努力解决这个问题。基本上我的应用程序布局就像这样

app.component.ts
  -- navigation.component.ts : i.e this selector is in the app.component
  -- router-outlet

基本上导航栏是我拥有所有登录逻辑的地方,我正在使用Firebase,这是神奇的事情发生,用户登录并且他们的图像位于右上角,他们的名字等等。这一切都很可爱。我的问题是我想与其他组件共享这些数据。现在,在我们之前提供一些有用的建议后,我设置了一个服务,将导航组件中的数据传递给显示的其他组件之一,这是一个动态组件,这意味着当您单击链接时,它会在导航组件保持静态时动态加载因为它与路由器插座处于同一水平。所以当你第一次访问页面时,我的服务显示数据没有问题,我想这是因为构造函数触发一次,一切都按预期工作,但是当你导航回来时......没有...没有用户数据传递给这个组件,因为导航组件doest曾经做过ngOnInit,除非你的网站首次加载,如果你在那条路上...我希望我已经很好地解释了这一点,我对angular2相对较新,所以仍在学习..有些事情来了进入我脑海里的可能就是这个东西可以通过更高级的可观察物或事件发射器以某种方式实现吗?

SERVICE.TS

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

// https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service

@Injectable()
export class UserdataService {
  // Observable string sources
  private shareUserDataSRC = new Subject<string>();

  // Observable string streams
  userDataAvailable$ = this.shareUserDataSRC.asObservable();


  passUserToService(userdata: string) {
    this.shareUserDataSRC.next(userdata);
    console.log(" service " + userdata);
  }


}

NAVIGATION.TS

    import { Component, OnInit, Input } from '@angular/core';
    import { Router } from '@angular/router';
    import { UserdataService }     from '../userdata.service';

    @Component({
    selector: 'app-navigation',
    template: `
            <header class="mast-head">
                <ul class="list-reset logged-in">
                    <li class="user-welcome">
                        <span>Hi, </span>
                        <a class="go-to-profile" href="#">{{ user?.name }}</a>
                        <i class="open-options"></i>
                    </li>
                </ul>
            </header>

            <aside class="side-drawer">

            </aside>
    `,
    styleUrls: ['./navigation.component.css']
    })
    export class NavigationComponent implements OnInit  {

    user      = {};

    constructor(  private router: Router, private shareUser: UserdataService) {

    }


    ngOnInit() {
        console.log(this.user);
    }


        private _changeState(user: any = null) {
        if(user) {
        this.user      = this._getUserInfo(user)
        } else {
        this.user      = {};
        }
    }

    private _getUserInfo( user: any ): any {

        if(!user) {
        return {};
        }

        let data     = user.auth.providerData[0];

        this.shareUser.passUserToService(data);

        return {
        name: data.displayName,
        avatar: data.photoURL,
        email: data.email,
        provider: data.providerId
        };

    }

    private _getProvider( from: string ) {
        ...STUFF GOING ON HERE...
    }

    }

TEMPLATE-I-WANT-TO-DISPLAY.TS

    import { Component, OnInit } from '@angular/core';
    import {Observable} from 'rxjs/Observable';
    import { AdInterface} from '../interfaces';
    import { Router } from '@angular/router';
    import { UserdataService }     from '../userdata.service';
    import { Subscription }   from 'rxjs/Subscription';

    @Component({
    selector: 'app-list-adverts',
    template: `
                <h2 class="timestamp">
                {{ announced?.uid }}
                {{ announced?.displayName }}
                {{ announced?.photoURL }}
                {{ announced?.email }}      
                {{ announced?.providerId }}                                                        
                </h2>
    `
    })

    export class ListAdvertsComponent implements OnInit {

        subscription: any;
        announced: string;
        userServ: any;

        constructor( private router: Router, private shareUser: UserdataService ) { 
                        this.userServ = this.shareUser.userDataAvailable$;
                        this.subscription = this.userServ.subscribe(userdata => {
                            this.announced = userdata;
                            // console.log( JSON.stringify(this.announced) );
                        });
                    }


        ngOnInit() {
        }

        ngOnDestroy() {
            // prevent memory leak when component destroyed
            this.subscription.unsubscribe();
        }

    }

1 个答案:

答案 0 :(得分:2)

Angular有一个完美的依赖注入系统,可能有助于解决您的问题。

我假设您在应用程序的某些功能模块中提供了UserdataService。尝试在AppModule上提供它:

import { UserdataServce } from './path/to/service.ts';

@NgModule({
    imports: [...],
    declarations: [...],
    providers: [
        ...
        UserdataService,
        ...
    ],
    bootstrap: [...]
})
export class AppModule {}

通过这种方式,您可以确保您的组件现在可以获得UserdataService的相同实例。