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

标签 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,这就是奇迹发生的地方,用户登录,他们的图像位于右上角,他们的名字等等......这一切都很可爱。我的问题是我想与其他组件共享这些数据。现在,经过一些有用的建议后,我设置了一项服务,将数据从导航组件传递到显示的其他组件之一,这是一个动态组件,这意味着当您单击链接时,它会动态加载,而导航组件保持静态因为它与路由器 socket 位于同一水平面上。因此,使用我的服务,当您第一次访问页面时,数据不会出现问题,我想这是因为构造函数触发一次并且一切都按预期工作,但是当您向后导航时......什么都没有......没有用户数据传递到此组件,并且因为导航组件不会执行 ngOnInit ,除非站点首次加载时(如果您在该路线上)。我希望我已经很好地解释了这一点,我对 Angular2 相对较新,所以仍在学习中。在我的脑海中,也许这可以通过更先进的可观察量或事件发射器以某种方式实现?

服务.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);
  }


}

导航.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...
    }

    }

模板-我想显示.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();
        }

    }

最佳答案

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

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

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

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

这样您就可以确保您的组件现在可以获得相同的 UserdataService 实例。

关于Angular2 - 不同级别组件之间的持久服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40643060/

相关文章:

Angular 2 RC6 - 在 URL 中设置默认参数并重定向到带有参数的路由

node.js - 如何将 Node 模块下载到 Angular 2 项目

javascript - 在两个 Angular 2 组件 typescript 文件之间传递值

html - 如何在 Angular 中设置我自己的 CSS 和 HTML

Angular 2+ 是否可以避免全局 CSS?

angular - 模板更改@Prop() 检测

angular - Electron 浏览器窗口防止Ctrl + W关闭窗口

angular - 如何在 Angular4/TypeScript 中以编程方式打开 ng-datetime-picker 的选择对话框?

html - 我收到错误消息:找不到bootstrap.min.css(404)。所有CSS和字体都会出现此错误

javascript - navigate 和 navigateByUrl 在 2.0.0-rc.1 上的 ngOnInit 中无法正常工作