Angular 在角度组件之间共享字符串

Angular 在角度组件之间共享字符串,angular,typescript,firebase,Angular,Typescript,Firebase,我试图接触Firebase数据库,获取存储的设置,然后在AppComponent中设置这些变量,然后从导入AppComponent的任何其他组件检索该字符串 我的AppComponent中有这个(它检索设置并将它们单独或作为一个组进行设置。让我们将公司作为我们尝试共享的变量 export class AppComponent { public company: string; public title: string; public version: string;

我试图接触Firebase数据库,获取存储的设置,然后在AppComponent中设置这些变量,然后从导入AppComponent的任何其他组件检索该字符串

我的AppComponent中有这个(它检索设置并将它们单独或作为一个组进行设置。让我们将
公司
作为我们尝试共享的变量

export class AppComponent {
    public company: string;
    public title: string;
    public version: string;
    public show: boolean = false;
    public settings: Observable<any>;

    constructor(private dropConfig: NgbDropdownConfig, private router: Router, private db: AngularFireDatabase, public authService: AuthService, private afAuth: AngularFireAuth) {
        afAuth.authState.subscribe(user => {
            if(user) {
                this.authService.findCompany().then((resp) => {
                    this.db.object(resp['company']+'/settings/users/'+user.uid+'/').valueChanges().subscribe((user) => {
                        this.company = resp['company'];
                        dropConfig.placement = 'bottom-right';
                        this.settings = db.object(this.company+'/settings/general').valueChanges();
                        this.settings.subscribe((setting) => {
                            this.title = setting.title;
                            this.version = setting.version;
                            this.show = true;
                        });
                    })
                });
            } else {
                this.show = false;
            }
        });
    }

    ngOnInit() {

    }
}
这是我在控制台中得到的:(简而言之,为了简单起见)

现在,如果我将console.log更改为以下内容:

console.log(this.appComp.company)
这是我在控制台中得到的

undefined
接收此信息的正确方法是什么?当我将其留在appComp时,它是可用的,但当我尝试进入阵列时,似乎所有信息都消失了

更新

根据下面的评论,我创建了一个服务(尽我所能),将所有这些设置放置在一个对象中,然后尝试返回该对象。该服务如下所示

import { Injectable } from '@angular/core';
import { AngularFireAuth } from '@angular/fire/auth';
import { AuthService } from '../auth/auth.service';
import { AngularFireDatabase, AngularFireObject } from '@angular/fire/database';
import * as firebase from 'firebase/app';
import { Observable } from 'rxjs';
import { tap, delay, map, first } from 'rxjs/operators';

@Injectable({
    providedIn: 'root'
})
export class DefaultsService {

    public sets: Observable<any>;
    public settings = {
        "show" : false,
        "company" : null,
        "title" : null,
        "version" : null
    }

    constructor(private authService: AuthService, private afAuth: AngularFireAuth, private db: AngularFireDatabase) {
        this.afAuth.authState.subscribe(user => {
            if(user) {
                this.authService.findCompany().then((resp) => {
                    this.sets = this.db.object(resp["company"]+'/settings/general').valueChanges();
                    this.sets.subscribe((response) => {
                        this.settings.show = true;
                        this.settings.company = resp["company"];
                        this.settings.title = response["title"];
                        this.settings.version = response["version"];
                    });
                });
            }
        });
    }
}

这是角度服务的作业。您应该通过应用程序组件和导航栏组件使用注入共享的公共服务组件公开共享数据

import { Component, OnInit } from '@angular/core';
import { AngularFireDatabase } from '@angular/fire/database';
import { AngularFireAuth } from '@angular/fire/auth';
import { AuthService } from './auth/auth.service';
import { DefaultsService } from './defaults/defaults.service';
import { Observable } from 'rxjs';
import { NgbDropdownConfig } from '@ng-bootstrap/ng-bootstrap';
import { filter, distinctUntilChanged, map, subscribeOn } from 'rxjs/operators';
import { ActivatedRoute, Router, NavigationStart, NavigationEnd, PRIMARY_OUTLET } from '@angular/router';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {

    public sets: Observable<any>;

    title: string;
    version: string;
    show: boolean;

    constructor(private dfServices: DefaultsService, private dropConfig: NgbDropdownConfig, 
      private router: Router, db: AngularFireDatabase, public authService: AuthService, 
      private afAuth: AngularFireAuth) {

        afAuth.authState.subscribe(user => {
          if(user) {
              this.authService.findCompany().then((resp) => {
                  this.sets = db.object(resp["company"]+'/settings/general').valueChanges();
                  this.sets.subscribe((response) => {
                      dfServices.settings = {
                        "show" : true,
                        "company" : resp["company"],
                        "title" : response["title"],
                        "version" : response["version"]
                    };
                  });
              });
          }
        });
    }

    ngOnInit() {
    }
}
在任何组件中,您都应该订阅,因为您不知道对服务器的调用实际何时结束:

import { Component, OnInit } from '@angular/core';
import { AngularFireDatabase } from '@angular/fire/database';
import { AngularFireAuth } from '@angular/fire/auth';
import { AuthService } from './auth/auth.service';
import { DefaultsService } from './defaults/defaults.service';
import { Observable } from 'rxjs';
import { NgbDropdownConfig } from '@ng-bootstrap/ng-bootstrap';
import { filter, distinctUntilChanged, map, subscribeOn } from 'rxjs/operators';
import { ActivatedRoute, Router, NavigationStart, NavigationEnd, PRIMARY_OUTLET } from '@angular/router';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {

  public sets: Observable<any>;

  title: string;
  version: string;
  show: boolean;

  constructor(private dfServices: DefaultsService, private dropConfig: NgbDropdownConfig,
    private router: Router, db: AngularFireDatabase, public authService: AuthService,
    private afAuth: AngularFireAuth) {
  }


  ngOnInit() {
    this.dfServices.getSettings.subscribe((settings: any)=> {
      console.log(settings);
    });
  }
}
从'@angular/core'导入{Component,OnInit};
从'@angular/fire/database'导入{AngularFireDatabase};
从'@angular/fire/auth'导入{AngularFireAuth};
从“./auth/auth.service”导入{AuthService};
从“./defaults/defaults.service”导入{DefaultsService};
从“rxjs”导入{Observable};
从'@ng bootstrap/ng bootstrap'导入{NgbDropdownConfig};
从“rxjs/operators”导入{filter,distinctUntilChanged,map,subscribeOn};
从'@angular/Router'导入{ActivatedRoute,Router,NavigationStart,NavigationEnd,PRIMARY_OUTLET};
@组成部分({
选择器:'应用程序根',
templateUrl:“./app.component.html”,
样式URL:['./app.component.css']
})
导出类AppComponent{
公共场景:可观察;
标题:字符串;
版本:字符串;
显示:布尔;
构造函数(私有DfsServices:DefaultsService,私有dropConfig:NgbDropdownConfig,
专用路由器:路由器,db:AngularFireDatabase,公共authService:authService,
私人afAuth:AngularFireAuth){
}
恩戈尼尼特(){
此.dfServices.getSettings.subscribe((设置:任意)=>{
控制台日志(设置);
});
}
}

好的,那么将其放在组件或服务中(技术性除外)有什么区别呢?如果我只是从组件将代码复制并粘贴到服务中,它不会提供相同的结果吗?不是试图听起来粗鲁,只是学习。服务是可注入的。你可以向Angular的某个注入器注册服务,这样它就可以被注入注入到任何组件中。(组件不可注入,无法在注入器中注册。)此外,在
注入器注册的服务是单例服务,这意味着它的数据与每个组件共享。组件的数据不能共享。一旦用户离开组件,它的数据就消失了。有关更多信息,请查看此处的文档:良好软件设计实践:关注点分离。将数据保存在我这里有一个非常简单的服务示例:仍然导致
未定义
。不,组件不是“可注入的”不应将其作为参数添加到构造函数中。您需要按照@SteveBoyd的建议构建服务。这就需要这样做,因此我必须将我放入
app.component.ts
中的代码放入我想在其中使用的所有其他组件中。这完全消除了我想做的事情。我希望能够通过只需在每个组件中调用
this.title=dfServices.getSettings().title
。实际上,不必在每个组件中放入与app.component.ts
相同的代码,在任何其他组件中只需调用
dfServices.getSettings().title
并且您应该拥有title值。并且不要将任何代码直接放在构造函数中,相反,您应该添加一个名为
ngOnInit()
的方法,Angular在创建组件后立即调用该方法。
ngOnInit():void{……此处的初始化代码…}
So在我的
navbar.component.ts中
I放入
console.log(this.dfServices.getSettings().title);
在我的
ngOnInit()中
我在控制台中收到空值。这是在遵循您的答案之后。但是,如果我将它放在仪表板组件中,它会正常工作,就像您所说的那样。奇怪的是,它在navbar组件中不工作。可能只是将navbar html放回
app.component.html
文件中,而不是将其分开。
import { Component, OnInit } from '@angular/core';
import { AngularFireDatabase } from '@angular/fire/database';
import { AngularFireAuth } from '@angular/fire/auth';
import { AuthService } from './auth/auth.service';
import { DefaultsService } from './defaults/defaults.service';
import { Observable } from 'rxjs';
import { NgbDropdownConfig } from '@ng-bootstrap/ng-bootstrap';
import { filter, distinctUntilChanged, map, subscribeOn } from 'rxjs/operators';
import { ActivatedRoute, Router, NavigationStart, NavigationEnd, PRIMARY_OUTLET } from '@angular/router';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
    title: string;
    version: string;
    show: boolean;

    constructor(private dfServices: DefaultsService, private dropConfig: NgbDropdownConfig, private router: Router, db: AngularFireDatabase, public authService: AuthService, private afAuth: AngularFireAuth) {
        afAuth.authState.subscribe(user => {
            if(user) {
                console.log(dfServices.settings);
                this.show = dfServices.settings.show;
                this.title = dfServices.settings.title;
                this.version = dfServices.settings.version
            }
        });
    }

    ngOnInit() {
    }
}
import { Component, OnInit } from '@angular/core';
import { AngularFireDatabase } from '@angular/fire/database';
import { AngularFireAuth } from '@angular/fire/auth';
import { AuthService } from './auth/auth.service';
import { DefaultsService } from './defaults/defaults.service';
import { Observable } from 'rxjs';
import { NgbDropdownConfig } from '@ng-bootstrap/ng-bootstrap';
import { filter, distinctUntilChanged, map, subscribeOn } from 'rxjs/operators';
import { ActivatedRoute, Router, NavigationStart, NavigationEnd, PRIMARY_OUTLET } from '@angular/router';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {

    public sets: Observable<any>;

    title: string;
    version: string;
    show: boolean;

    constructor(private dfServices: DefaultsService, private dropConfig: NgbDropdownConfig, 
      private router: Router, db: AngularFireDatabase, public authService: AuthService, 
      private afAuth: AngularFireAuth) {

        afAuth.authState.subscribe(user => {
          if(user) {
              this.authService.findCompany().then((resp) => {
                  this.sets = db.object(resp["company"]+'/settings/general').valueChanges();
                  this.sets.subscribe((response) => {
                      dfServices.settings = {
                        "show" : true,
                        "company" : resp["company"],
                        "title" : response["title"],
                        "version" : response["version"]
                    };
                  });
              });
          }
        });
    }

    ngOnInit() {
    }
}

import { Injectable } from '@angular/core';
import { AngularFireAuth } from '@angular/fire/auth';
import { AuthService } from '../auth/auth.service';
import { AngularFireDatabase, AngularFireObject } from '@angular/fire/database';
import * as firebase from 'firebase/app';
import { Observable } from 'rxjs';
import { tap, delay, map, first } from 'rxjs/operators';

@Injectable({
    providedIn: 'root'
})
export class DefaultsService {

    public sets: Observable<any>;
    public settings = {
        "show" : false,
        "company" : null,
        "title" : null,
        "version" : null
    }

    constructor(private authService: AuthService, private afAuth: AngularFireAuth, private db: AngularFireDatabase) {
    }

    getSettings() {
      return this.settings;
    }
}

import { Injectable } from '@angular/core';
import { AngularFireAuth } from '@angular/fire/auth';
import { AuthService } from '../auth/auth.service';
import { AngularFireDatabase, AngularFireObject } from '@angular/fire/database';
import * as firebase from 'firebase/app';
import { Observable } from 'rxjs';
import { tap, delay, map, first } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class DefaultsService {

  public sets: Observable<any>;

  private settingsObs = null;

  constructor(private authService: AuthService, private afAuth: AngularFireAuth, private db: AngularFireDatabase) {
    this.createSettingsObs();
  }

  getSettings() {
    return this.settingsObs;
  }

  createSettingsObs() {

    this.settingsObs = Observable.create(function (observer) {

      this.afAuth.authState.subscribe(user => {
        if (user) {
          this.authService.findCompany().then((resp) => {
            this.sets = this.db.object(resp["company"] + '/settings/general').valueChanges();
            this.sets.subscribe((response) => {
              const settings = {
                "show": true,
                "company": resp["company"],
                "title": response["title"],
                "version": response["version"]
              };
              observer.next(settings);
            });
          });
        }
      });
    });
  }
}

import { Component, OnInit } from '@angular/core';
import { AngularFireDatabase } from '@angular/fire/database';
import { AngularFireAuth } from '@angular/fire/auth';
import { AuthService } from './auth/auth.service';
import { DefaultsService } from './defaults/defaults.service';
import { Observable } from 'rxjs';
import { NgbDropdownConfig } from '@ng-bootstrap/ng-bootstrap';
import { filter, distinctUntilChanged, map, subscribeOn } from 'rxjs/operators';
import { ActivatedRoute, Router, NavigationStart, NavigationEnd, PRIMARY_OUTLET } from '@angular/router';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {

  public sets: Observable<any>;

  title: string;
  version: string;
  show: boolean;

  constructor(private dfServices: DefaultsService, private dropConfig: NgbDropdownConfig,
    private router: Router, db: AngularFireDatabase, public authService: AuthService,
    private afAuth: AngularFireAuth) {
  }


  ngOnInit() {
    this.dfServices.getSettings.subscribe((settings: any)=> {
      console.log(settings);
    });
  }
}