使用 service/broadcasting 的组件通信:Angular2
Component communication using service/broadcasting : Angular2
大家好我是angular2的初学者。我正在创建一个用于学习目的的小型演示应用程序。
app.component.ts
template: `
<header-content></header-content>
<main-content></main-content>
<footer-content></footer-content>
`
在我的 header 中,我有一个导航部分,例如主页、登录等。
Main-content-template结构
<div class="container main">
<div class="row">
<router-outlet></router-outlet>
</div>
</div>
如您所见,我已将 header 和页脚部分 link 的 router-outlet 放在 main-content.
中
默认我在登录页面/login.
我每个 link 都有一个单独的组件。
我想要的是,当用户点击登录页面上的提交按钮时,我将他重定向到其他一些 xyz page.But,同时我希望我的登录名 link 从 header导航并显示用户名。
<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);
});
}
}
Login-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;
}
}
我在 Whosebug 上阅读了很多其他问答博客,并且我尝试使用 observable,正如您在代码中看到的那样。但是当我点击提交按钮时,不会调用 ngOnInit() ( this.loginService.getLogged().subscribe((logged) => { ) 中的代码行来更新 isUserLoggedIn 的值。
我怎样才能广播或触发某种机制,有哪些方法和最好的方法。
我不知道我在做什么错误。
我的另一个问题是 header-content 中的方法如何与其兄弟 main-content 或footer-content 以及 parent my-app 组件 section.As 在许多问题中的答案是有 parent child 组件,但没有兄弟姐妹。
感谢任何帮助!!!
谢谢
在您的 login-service
中,您调用 returns 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();
}
}
在做了太多实验之后我发现了我正在做的错误,我没有创建一个单独的登录服务,而是将其作为共享服务,我从每个组件中删除了声明 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();
});
}
大家好我是angular2的初学者。我正在创建一个用于学习目的的小型演示应用程序。
app.component.ts
template: `
<header-content></header-content>
<main-content></main-content>
<footer-content></footer-content>
`
在我的 header 中,我有一个导航部分,例如主页、登录等。
Main-content-template结构
<div class="container main">
<div class="row">
<router-outlet></router-outlet>
</div>
</div>
如您所见,我已将 header 和页脚部分 link 的 router-outlet 放在 main-content.
中默认我在登录页面/login.
我每个 link 都有一个单独的组件。
我想要的是,当用户点击登录页面上的提交按钮时,我将他重定向到其他一些 xyz page.But,同时我希望我的登录名 link 从 header导航并显示用户名。
<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);
});
}
}
Login-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;
}
}
我在 Whosebug 上阅读了很多其他问答博客,并且我尝试使用 observable,正如您在代码中看到的那样。但是当我点击提交按钮时,不会调用 ngOnInit() ( this.loginService.getLogged().subscribe((logged) => { ) 中的代码行来更新 isUserLoggedIn 的值。
我怎样才能广播或触发某种机制,有哪些方法和最好的方法。
我不知道我在做什么错误。
我的另一个问题是 header-content 中的方法如何与其兄弟 main-content 或footer-content 以及 parent my-app 组件 section.As 在许多问题中的答案是有 parent child 组件,但没有兄弟姐妹。
感谢任何帮助!!!
谢谢
在您的 login-service
中,您调用 returns 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();
}
}
在做了太多实验之后我发现了我正在做的错误,我没有创建一个单独的登录服务,而是将其作为共享服务,我从每个组件中删除了声明 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();
});
}