Angular 使用服务在组件之间共享数据

Angular 使用服务在组件之间共享数据,angular,service,Angular,Service,我一直在尝试在我的两个组件之间共享一些数据。这两个组件都通过我的主组件中的routerOutlet显示,如下所示: import { Component } from '@angular/core'; import { AccountService } from './account.service'; @Component({ moduleId: module.id, selector: 'my-app', templateUrl: 'app.component.html', provide

我一直在尝试在我的两个组件之间共享一些数据。这两个组件都通过我的主组件中的routerOutlet显示,如下所示:

import { Component } from '@angular/core';
import { AccountService } from './account.service';

@Component({
moduleId: module.id,
selector: 'my-app',
templateUrl: 'app.component.html',
providers: [AccountService]
})
export class AppComponent  { 

constructor(public accountService:AccountService){

}

}
import { Component } from '@angular/core';
import { AccountService } from './account.service';

@Component({
moduleId: module.id,
selector: 'home-component',
templateUrl: 'home.component.html',
})

export class HomeComponent  {  


constructor(public accountService:AccountService){
}
}
我有一个登录组件,试图在我的服务中设置一个值,如下所示:

import { Component } from '@angular/core';
import { AccountService } from './account.service';

@Component({
moduleId: module.id,
selector: 'login-component',
templateUrl: 'login.component.html',
})
export class LoginComponent  {


constructor(public accountService:AccountService){
}

setAccount(userName: string, password: string){
    this.accountService.setAccount(userName,password); 
} 

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

export class Account{
    name: string;
    password: string;
}

@Injectable()
    export class AccountService  {  

    private account: BehaviorSubject<Account>; 

   constructor() {
       this.account = <BehaviorSubject<Account>>new BehaviorSubject({});
   }
   getAccount(){
       return this.account.asObservable();
   }

   setAccount(username: string, password: string){
       this.account.next({name: username, password: password})
   }
}
从我的模板调用setAccount方法。现在,在另一个组件中,我试图从服务中获取帐户并显示用户名,但这不起作用。另一个组件如下所示:

import { Component } from '@angular/core';
import { AccountService } from './account.service';

@Component({
moduleId: module.id,
selector: 'my-app',
templateUrl: 'app.component.html',
providers: [AccountService]
})
export class AppComponent  { 

constructor(public accountService:AccountService){

}

}
import { Component } from '@angular/core';
import { AccountService } from './account.service';

@Component({
moduleId: module.id,
selector: 'home-component',
templateUrl: 'home.component.html',
})

export class HomeComponent  {  


constructor(public accountService:AccountService){
}
}
我在模板中显示如下用户名:

{{accountService.getAccount().name}}
最后,我的服务是:

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


export class Account{
name: string;
password: string;
}

@Injectable()
export class AccountService  {  

private account = {name: "", password: ""};

getAccount(){

return this.account;
}

setAccount(username: string, password: string){
this.account.name = username;
this.account.password = password;
}

}
我做错了什么

编辑:问题似乎是当显示第二个组件时,页面被重新加载,从而导致服务重新启动?这是我的登录组件的HTML,因为我怀疑问题可能在这里:

    <div class="topbar">
    <a title="Made for the University of Southern Denmark." href="login.html">
        <img src="img/sdulogo.png">
    </a>
</div>
<div class="logincontainer">
<img src="img/profilepic.png">
    <form action="/home">
        <div class="form-input">
            <input #username type="text" id="username" 
            placeholder="Enter Username" required>
        </div>

            <div class="form-input">
            <input #password type="password" id="password"
            placeholder="Enter Password" required>
        </div>
        <button (click)="setAccount(username.value, password.value)" type="submit" class="btn-login">LOGIN</button><br>
        <a href="http://www.google.dk">Create Account</a><br>
        <a href="#">Forgot Password?</a>
        <p>{{accountService.getAccount().name}}</p>
    </form>


</div>

登录

{{accountService.getAccount().name}

您可以使用

您的服务应该如下所示:

import { Component } from '@angular/core';
import { AccountService } from './account.service';

@Component({
moduleId: module.id,
selector: 'login-component',
templateUrl: 'login.component.html',
})
export class LoginComponent  {


constructor(public accountService:AccountService){
}

setAccount(userName: string, password: string){
    this.accountService.setAccount(userName,password); 
} 

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

export class Account{
    name: string;
    password: string;
}

@Injectable()
    export class AccountService  {  

    private account: BehaviorSubject<Account>; 

   constructor() {
       this.account = <BehaviorSubject<Account>>new BehaviorSubject({});
   }
   getAccount(){
       return this.account.asObservable();
   }

   setAccount(username: string, password: string){
       this.account.next({name: username, password: password})
   }
}
在home.component.ts中:

private account:Account;
constructor(private accountService:AccountService){}

getAccount() {
    this.accountService.getAccount().subscribe(account => this.account = account)
}

ngOnInit(): void {
    // example of usage
    this.getAccount()
}
在主模板中,像这样使用它
{{account.name}


希望这有帮助

您是否可以尝试将AccountService添加为NgModule中的提供程序,而不是将其添加为app.component中的提供程序?

在控制台中是否看到任何错误消息?如果是,请将它们添加到您的问题中。没有任何错误消息。作为应用程序的用户,您从登录页面转到主页的操作顺序是什么?我的猜测是您重新加载了页面。@jbnize如果完全正确,页面实际上正在重新加载。我没有想到这一点。如何避免?如果在登录后使用router.navigate()转到主页,则不应发生这种情况。但是您无法阻止用户重新加载页面,因此您无论如何都需要处理这种可能性,例如,将用户的ID/令牌存储在本地存储中,如果用户信息在内存中不可用,则从服务器获取用户信息。在任何地方存储密码都不是一个明智的想法。为什么登录后需要密码?附录:您的表单不应具有
action
属性。身份验证应通过编程方式从登录组件进行处理。我一直在我的NgModule中使用它。然后请尝试从应用程序组件中删除它。当服务用作特定组件中的提供程序时,该组件本身将存在一个新的服务实例。因此,在我们需要跨组件共享数据的服务的情况下,我们不能在组件的提供者中指定它们,而只能在NgModule中指定它们。