我试图在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的身份验证方法登录/注册。然后,我检索用户的唯一ID,并希望将该字符串传递给update.ts
组件,以便它可以在Firebase实时数据库中创建该名称下的节点。请注意,在使用firebase时,我也使用了Angular的Fire库。
//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>
在<<p> strong> 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>
所以当我试图通过sendUserData()
发送数据在auth.component.ts文件,它工作。我也能够在控制台窗口中打印User Id。在update.component.ts,然而,当我订阅可观察对象时,我仍然收到"空"。这是否意味着它没有改变值?
我已经尝试在ts
文件中订阅ngOnInit()
中的可观察对象,但仍然没有返回适当的值。我错过什么了吗?我一直在遵循这个教程。
编辑1:重要提示(我认为?),这两个组件也作为两个不同的路线。下面是在app-routing.module.ts中设置的路由
const routes: Routes = [
{ path:'', component:TestUpdateComponent },
{ path:'auth', component:AuthComponentComponent }
];
问题实际上与我试图在不同路由的组件之间共享数据这一事实有关。因此,这些是不相关的组件,我不能使用共享数据的标准方法(例如,从父组件到子组件或兄弟组件之间)。
我遵循了这个网站上的第三个例子。我通过ng g s shared
命令创建了一个简单的服务。我把这个服务导入到我的app.module.ts文件,并将其作为providers
.
shared.service.tsfile非常简单,因为我只想传递一个字符串:
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);
}
打印出值。如果我没记错的话,这个方法还使这个变量对所有访问这个特定提供者的组件都是全局可用的。
嗯,我检查了你的代码,问题可能是由很多原因引起的,但我认为问题是你在多个模块中提供了这个服务。
确保只在声明了两个组件的一个模块中或在app.module.ts
中提供此服务我的建议是创建一个components.module.ts
,并在那里声明所有的组件,这样你就可以在任何你想要的地方导入它。
我还建议你在服务中声明一个公共变量,而不是这些令人困惑的setter和getter,这样你就可以在任何地方更新它,它也会在其他地方更新。