我有2個Angular2組件,我希望能夠共享一個值。兩個Angular2組件之間的通信問題
我的應用組件的代碼是:其在<router-outlet></router-outlet>
加載
<app-header></app-header>
<router-outlet></router-outlet>
<app-footer></app-footer>
我的登錄組件打字稿代碼是:
import { Component, OnInit } from '@angular/core';
import { MatInput } from '@angular/material';
import { Router } from '@angular/router';
import { LoginService } from '../../services/login.service';
import { User } from '../../models/user';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
providers: [ LoginService ],
styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
public user = new User('', '', new Array<string>());
public errorMsg = '';
public isLoading = false;
constructor(
private loginService: LoginService,
private router: Router
) { }
ngOnInit() {
if (this.loginService.getCurrentUser() !== null) {
this.router.navigate(['home']);
}
}
login() {
this.isLoading = true;
const obs = this.loginService.login(this.user);
obs.subscribe(
res => {
if (res !== true) {
this.errorMsg = 'Incorrect Username/Password';
this.loginService.loginStatusChange(false);
} else {
this.loginService.loginStatusChange(true);
}
},
err => {
this.isLoading = false;
this.errorMsg = err._body;
this.loginService.loginStatusChange(false);
},
() => {
this.isLoading = false;
}
);
obs.connect();
}
}
我的標題組件打字稿是:
import { Component, OnInit } from '@angular/core';
import { User } from '../../models/user';
import { LoginService } from '../../services/login.service';
@Component({
selector: 'app-header',
templateUrl: './header.component.html',
providers: [ LoginService ],
styleUrls: ['./header.component.css']
})
export class HeaderComponent implements OnInit {
public currentUser: string;
constructor(private loginService: LoginService) { }
ngOnInit() {
const currentUser = this.loginService.getCurrentUser();
if (currentUser !== null) {
this.currentUser = currentUser.username;
}
this.loginService.loginObservable
.map((status) => {
if (status) {
return this.loginService.getCurrentUser();
}
return null;
}
)
.subscribe((user) => {
const thisUser = this.loginService.getCurrentUser();
if (thisUser !== null) {
this.currentUser = thisUser.username;
}
});
}
logout() {
this.loginService.logout();
this.loginService.loginStatusChange(false);
}
}
而最後我的標題組件視圖是:
<div id="wrapper">
<section>
<div id="topHeader">
<div class="oLogo">
<img id="OLogoImg" src="../../assets/images/Luceco-O-Logo-Transparent.png" alt="o-logo" height="20" />
</div>
</div>
</section>
</div>
<div class="container body-content">
<div id="header">
<div class="pageWrap">
<a id="logo" >
<img id="logoImg" src="../../assets/images/Luceco-Logo-Transparent.png" alt="logo" height="28" />
</a>
<ul id="menu">
<li id="home-menu" class="top-level home-menu">
<a href="#">Home</a>
</li>
<--FOLLOWING COMPONENT NEEDS TO BE DISPLAYED AFTER LOGIN -->
<li *ngIf="currentUser != null" id="logout-menu" class="top-level logout-menu">
<a href="#" (click)="logout()">Log Out</a>
</li>
</ul>
</div>
</div>
login服務:
import { Injectable } from '@angular/core';
import { Http, Headers, RequestOptions, Response } from '@angular/http';
import { Router } from '@angular/router';
import 'rxjs/rx';
import { ConnectableObservable } from 'rxjs/rx';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Observable } from 'rxjs/Observable';
import { User } from '../models/user';
@Injectable()
export class LoginService {
private authApiUrl = 'http://192.168.1.201/ForkliftHelperAPI/api/Auth';
private loginBehaviourSubject = new BehaviorSubject<boolean>(false);
public loginObservable = this.loginBehaviourSubject.asObservable();
constructor(private router: Router,
private _http: Http) { }
loginStatusChange(isLoggedIn: boolean) {
this.loginBehaviourSubject.next(isLoggedIn);
}
login(user: User): ConnectableObservable<any> {
let result: User;
const body = JSON.stringify(user);
const headers = new Headers({
'Content-Type': 'application/json'
});
const options = new RequestOptions({
headers: headers
});
const obsResponse = this._http.post(this.authApiUrl, body, options)
.map(res => res.json())
.publish();
obsResponse.subscribe(
(res: User) => {
result = res;
if (result) {
user.securityGroups = result.securityGroups;
sessionStorage.setItem('user', JSON.stringify(user));
this.router.navigate(['home']);
}
},
err => console.log(err)
);
return obsResponse;
}
logout() {
sessionStorage.removeItem('user');
this.router.navigate(['login']);
}
getCurrentUser() {
const storedUser = JSON.parse(sessionStorage.getItem('user'));
if (!storedUser) {
return null;
}
return new User(storedUser.username, storedUser.password, storedUser.securityGroups);
}
isLoggedIn() {
if (this.getCurrentUser() === null) {
this.router.navigate(['login']);
}
}
}
所以基本上我的問題是,當LoginComponent的登錄方法完成,我希望它的HeaderComponent內設置currentUser變量,以便在產生下頁通過路由器插座,標題正確顯示註銷按鈕。如果在重定向之後手動刷新頁面,則更新會正確發生,但是,在重定向時不會刷新標題,而只會刷新router-outlet的內容。
我已經嘗試使用服務以及使用@Input()和@Output()但沒有運氣,也許我一直在錯誤地使用它們。
我的主要問題似乎是,當重定向和導航發生時,頁眉和頁腳組件不會刷新,因爲它只是<router-outlet></router-outlet>
中受影響的組件。我這樣做是爲了防止在每個其他組件中都有頁眉和頁腳組件,但如果這是實現我所需的唯一方法,那麼就這樣做吧。
任何幫助將不勝感激。
將不勝感激,如果你可以做一個再現,看你做了什麼的 – amal
可能的複製[Angular2 - 使用服務的組件之間共享數據(https://stackoverflow.com/questions/35273106/angular2-share-data-between-components-using-services) –
最有可能是dup –