在 Angular 中使用共享服务在同级组件之间共享数据返回空
Sharing Data between Sibling Components using Shared Service returning empty in Angular
我试图在 Angular 中的两个同级组件之间共享一个字符串,但它似乎对我不起作用。
我有两个组件,auth.component.ts
和 update.component.ts
。然后我有一个名为 shared.service.ts
.
的服务
编辑 2:
我根据评论中的建议包括了整个 shared.services.ts 文件。
shared.service.ts
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class SharedService {
private useridSource = new BehaviorSubject('empty');
useridMessage$ = this.useridSource.asObservable();
constructor() { }
sendUserId(userId:string) {
this.useridSource.next(userId);
}
}
auth
组件的目的是允许用户通过 firebase 的身份验证方法 login/sign up。然后我检索用户的唯一 ID 并想将该字符串传递给 update.ts
组件,以便它可以在 Firebase 实时数据库中以该名称创建一个节点。请注意,我在使用 firebase 时也使用 Angular Fire Library。
这是来自 auth.component.ts
的代码片段
//I store the unique ID created by firebase in this string
userId?:string;
//I inject the AngularFireAuth from the Angular Fire library as well as my Shared Service
constructor(public auth: AngularFireAuth, private sharedService: SharedService ) { }
//the user logs in or signs up using google
login() {
this.auth.signInWithPopup(new firebase.auth.GoogleAuthProvider());
}
//this function sets the userId string - if I console.log() this string, it prints out correctly
printUserId() {
this.auth.authState.subscribe( authState => {
this.currentAuth = authState;
this.userId = this.currentAuth.uid;
})
}
//I use this function to send the data via the shared service when a button is pressed in the HTML file.
sendUserData(){
if(this.userId) {
console.log(this.userId);
this.sharedService.sendUserId(this.userId);
} else {
console.log("User Id has not been set");
}
}
在 auth.component.html 文件中,我通过以下方式将数据发送到服务:
<button (click)="sendUserData()"> Send Current User </button>
在update.component.ts,收到数据,想打印出来
//string to receive the data in
userId?:string;
//inject the shared service. The CrowboxdbService is another service I use to interact with firebase
constructor(private cbservice: CrowboxdbService, private sharesService: SharedService) {
}
//this function is invoked when a button is pressed in the view (HTML file)
getUserId(){
this.sharesService.useridMessage$.subscribe(x => {
this.userId = x;
console.log(this.userId);
}
);
}
在update.component.html
<button (click)="getUserId()">Get User ID </button>
<h1>User Id is: {{userId}}</h1>
因此,当我尝试通过 auth.component.ts 文件中的 sendUserData()
发送数据时,它起作用了。我也可以在控制台 window 中打印用户 ID。然而,在 update.component.ts 中,当我订阅可观察对象时,我仍然收到“空”。这是否意味着它没有更改值?
我已经尝试在两个 ts
文件中订阅 ngOnInit()
中的可观察对象,但仍然没有 return 正确的值。我错过了什么吗?我一直在关注 this tutorial.
编辑 1:
重要说明(我认为?),这两个组件也充当两条不同的路线。下面是在app-routing.module.ts
中设置的路由
const routes: Routes = [
{ path:'', component:TestUpdateComponent },
{ path:'auth', component:AuthComponentComponent }
];
好吧,我检查了你的代码,问题可能是由很多原因引起的,但我认为问题是你在多个模块中提供了这个服务。
确保您只在声明了两个组件的一个模块中或 app.module.ts
中提供此服务
我的建议是创建一个 components.module.ts
并在那里声明所有组件,这样您就可以将其导入到任何需要的地方。
我还建议您在服务中声明一个 public 变量,而不是这个令人困惑的 setter 和 getter,这样您就可以在任何地方更新它,它也会在其他地方更新。
这个问题实际上与我试图在不同路径的组件之间共享数据有关。因此,这些是不相关的组件,我无法使用共享数据的标准方法(例如,从父组件到子组件或兄弟组件之间)。
我遵循了 this website 中的第三个示例。我通过 ng g s shared
命令创建了一个简单的服务。我将此服务导入到我的 app.module.ts 文件中,并将其作为 providers
.
文件之一
shared.service.ts文件非常简单,因为我只想传递一个字符串:
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class SharedService {
public userId:any;
constructor() { }
}
然后,在auth.component.ts,需要发送数据的文件中,我有一个点击按钮时执行的功能。此函数检查之前是否已设置有问题的字符串(在这种情况下由用户登录)。如果设置了字符串,它会在提供者文件中设置字符串并导航到接收者组件页面。
//function is invoked by a button in the view page
sendUserData(){
if (this.userId) {
this.sharedService.userId = this.userId;
this.router.navigate(['data']);
} else {
console.log("User Id has not been set");
}
}
为了接收 update.component.ts 中的数据,我有一个简单的函数,它也是在单击按钮时执行的:
getUserId(){
this.userId = this.sharesService.userId;
console.log(this.userId);
}
这会打印出值。如果我没记错的话,此方法还使变量全局可供所有有权访问此特定提供程序的组件使用。
我试图在 Angular 中的两个同级组件之间共享一个字符串,但它似乎对我不起作用。
我有两个组件,auth.component.ts
和 update.component.ts
。然后我有一个名为 shared.service.ts
.
编辑 2: 我根据评论中的建议包括了整个 shared.services.ts 文件。
shared.service.ts
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class SharedService {
private useridSource = new BehaviorSubject('empty');
useridMessage$ = this.useridSource.asObservable();
constructor() { }
sendUserId(userId:string) {
this.useridSource.next(userId);
}
}
auth
组件的目的是允许用户通过 firebase 的身份验证方法 login/sign up。然后我检索用户的唯一 ID 并想将该字符串传递给 update.ts
组件,以便它可以在 Firebase 实时数据库中以该名称创建一个节点。请注意,我在使用 firebase 时也使用 Angular Fire Library。
这是来自 auth.component.ts
的代码片段 //I store the unique ID created by firebase in this string
userId?:string;
//I inject the AngularFireAuth from the Angular Fire library as well as my Shared Service
constructor(public auth: AngularFireAuth, private sharedService: SharedService ) { }
//the user logs in or signs up using google
login() {
this.auth.signInWithPopup(new firebase.auth.GoogleAuthProvider());
}
//this function sets the userId string - if I console.log() this string, it prints out correctly
printUserId() {
this.auth.authState.subscribe( authState => {
this.currentAuth = authState;
this.userId = this.currentAuth.uid;
})
}
//I use this function to send the data via the shared service when a button is pressed in the HTML file.
sendUserData(){
if(this.userId) {
console.log(this.userId);
this.sharedService.sendUserId(this.userId);
} else {
console.log("User Id has not been set");
}
}
在 auth.component.html 文件中,我通过以下方式将数据发送到服务:
<button (click)="sendUserData()"> Send Current User </button>
在update.component.ts,收到数据,想打印出来
//string to receive the data in
userId?:string;
//inject the shared service. The CrowboxdbService is another service I use to interact with firebase
constructor(private cbservice: CrowboxdbService, private sharesService: SharedService) {
}
//this function is invoked when a button is pressed in the view (HTML file)
getUserId(){
this.sharesService.useridMessage$.subscribe(x => {
this.userId = x;
console.log(this.userId);
}
);
}
在update.component.html
<button (click)="getUserId()">Get User ID </button>
<h1>User Id is: {{userId}}</h1>
因此,当我尝试通过 auth.component.ts 文件中的 sendUserData()
发送数据时,它起作用了。我也可以在控制台 window 中打印用户 ID。然而,在 update.component.ts 中,当我订阅可观察对象时,我仍然收到“空”。这是否意味着它没有更改值?
我已经尝试在两个 ts
文件中订阅 ngOnInit()
中的可观察对象,但仍然没有 return 正确的值。我错过了什么吗?我一直在关注 this tutorial.
编辑 1: 重要说明(我认为?),这两个组件也充当两条不同的路线。下面是在app-routing.module.ts
中设置的路由const routes: Routes = [
{ path:'', component:TestUpdateComponent },
{ path:'auth', component:AuthComponentComponent }
];
好吧,我检查了你的代码,问题可能是由很多原因引起的,但我认为问题是你在多个模块中提供了这个服务。
确保您只在声明了两个组件的一个模块中或 app.module.ts
我的建议是创建一个 components.module.ts
并在那里声明所有组件,这样您就可以将其导入到任何需要的地方。
我还建议您在服务中声明一个 public 变量,而不是这个令人困惑的 setter 和 getter,这样您就可以在任何地方更新它,它也会在其他地方更新。
这个问题实际上与我试图在不同路径的组件之间共享数据有关。因此,这些是不相关的组件,我无法使用共享数据的标准方法(例如,从父组件到子组件或兄弟组件之间)。
我遵循了 this website 中的第三个示例。我通过 ng g s shared
命令创建了一个简单的服务。我将此服务导入到我的 app.module.ts 文件中,并将其作为 providers
.
shared.service.ts文件非常简单,因为我只想传递一个字符串:
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class SharedService {
public userId:any;
constructor() { }
}
然后,在auth.component.ts,需要发送数据的文件中,我有一个点击按钮时执行的功能。此函数检查之前是否已设置有问题的字符串(在这种情况下由用户登录)。如果设置了字符串,它会在提供者文件中设置字符串并导航到接收者组件页面。
//function is invoked by a button in the view page
sendUserData(){
if (this.userId) {
this.sharedService.userId = this.userId;
this.router.navigate(['data']);
} else {
console.log("User Id has not been set");
}
}
为了接收 update.component.ts 中的数据,我有一个简单的函数,它也是在单击按钮时执行的:
getUserId(){
this.userId = this.sharesService.userId;
console.log(this.userId);
}
这会打印出值。如果我没记错的话,此方法还使变量全局可供所有有权访问此特定提供程序的组件使用。