大家好我是angular2的初学者。我正在创建一个用于学习目的的小型演示应用程序。
app.component.ts
template: `
<header-content></header-content>
<main-content></main-content>
<footer-content></footer-content>
`
在我的标题中,我有一个导航部分,如主页,登录等。
主要内容模板结构
<div class="container main">
<div class="row">
<router-outlet></router-outlet>
</div>
</div>
正如您所看到的,我已将主页内容中的页眉和页脚部分链接的路由器插座放置。
通过defalut我在登录页面/登录。
我为每个链接都有一个单独的组件。
我想要的是当用户点击登录页面上的提交按钮时,我将他重定向到其他一些xyz页面。但是我希望我的登录链接从标题导航中隐藏并显示用户名。
<li *ngIf='!isUserLoggedIn'><a routerLink="/login">Login</a></li>
<li *ngIf='isUserLoggedIn'><a>Welcome {{user}}</a></li>
HeaderComponent.ts
@Component({
moduleId : module.id,
selector : 'header-content',
templateUrl: 'Header.html',
providers: [LoginService]
})
export class HeaderComponent implements OnInit {
isUserLoggedIn = false;
user : string;
constructor(private loginService: LoginService) { }
getUserName() :void {
this.user = this.loginService.getUserName(); // reading data from localstorage on page refresh
if(this.user) {
this.isUserLoggedIn = true;
}
}
ngOnInit(): void {
this.getUserName();
// Will fire everytime other component use the setter this.loginService.setLogged()
this.loginService.getLogged().subscribe((logged) => {
console.log('Welcome===>', logged);
});
}
}
登录-Service.ts
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
import { Observable } from 'rxjs/Observable';
@Injectable()
export class LoginService {
username : string;
private logged: boolean;
private subject: Subject<boolean> = new Subject<boolean>();
setLogged(logged: boolean): void {
this.logged = logged;
this.subject.next(logged);
}
getLogged() {
return this.subject.asObservable();
}
constructor() {
if(localStorage.getItem('userName')){
this.username = localStorage.getItem('userName');
}
}
getUserName():string {
if(this.username)
return this.username;
}
}
我已经在stackoverflow上阅读了很多其他问题和答案的博客,我尝试使用observable,你可以在代码中看到。但是当我点击提交按钮时,为了更新isUserLoggedIn的值,没有调用ngOnInit()(this.loginService.getLogged()。subscribe((logged)=&gt; {)中的代码行。
我如何广播或触发某种机制,以及采用哪种方式和最佳方式。
我不知道我在做什么错误。
我的另一个问题是 header-content 中的方法如何与其兄弟主要内容或页脚内容进行通信,以及与父我的应用程序组件部分。在许多问题中,答案是父子组件,而不是兄弟姐妹。
任何帮助表示赞赏!!!
谢谢
答案 0 :(得分:1)
在login-service
中,您调用返回username
的方法。
这意味着你有一个承诺。
回到headerComponent,将get函数更改为:
getUserName() :void {
this.user = this.loginService
.getUserName()
.success(data => {
this.isUserLoggedIn = true;
}
}
我相信这会根据我在这里看到的问题解决您的问题。 我建议创建一个工作片段;)
<强>更新强>
根据您的评论,我建议您使用BehaviorSubject
,这样可以轻松地从服务广播到您想要的任何组件(从布尔到对象等)。
以下是基于您案例的示例:
在您的登录服务中(我只附加将导致这种情况发生的代码):
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Injectable } from '@angular/core';
@Injectable()
export class LoginService {
userUpdated: any;
constructor() {
this.userUpdated = new BehaviorSubject<any>(false);
}
getUserName() :void {
this.user = this.loginService
.getUserName()
.success(data => {
this.userUpdated.next(true);
return data;
}
}
}
接下来,您将转到headerComponent代码并对其进行编辑,以便订阅:
@Component({
moduleId : module.id,
selector : 'header-content',
templateUrl: 'Header.html',
providers: [LoginService]
})
export class HeaderComponent implements OnInit, OnDestroy {
isUserLoggedIn = false;
user : string;
sub: any;
constructor(private loginService: LoginService) { }
ngOnInit(): void {
this.sub = this.loginService.userUpdated.subscribe(
data => {
if(data.username) {
this.isUserLoggedIn = true;
}
);
}
ngOnDestroy() {
this.sub.unsubscribe();
}
}
答案 1 :(得分:0)
在做了太多实验之后,我发现了我正在做的错误,而不是创建一个单独的Login服务,我把它作为共享服务,我从每个组件中删除了语句providers:[LoginService]
并放置了这一行app.module.ts文件中的代码。
<强> HeaderComponent.ts 强>
ngOnInit(): void {
this.getUserName();
// Will fire everytime other component use the setter this.sharedService.setLogged()
this.sharedService.getLogged().subscribe((logged) => {
console.log("logged==", logged);
this.isUserLoggedIn = logged;
this.user = this.sharedService.getUserName();
});
}