问题
I'm loading some of div in between tag. Its as bellow.
Here is my index.html
<html>
<script>
System.import('app').catch(function(err){ console.error(err); });
</script>
</head>
<!-- 3. Display the application -->
<body>
<my-app>Loading...</my-app>
</body>
</html>
app.module.ts
@NgModule({
imports: [
BrowserModule,
FormsModule,
AppRoutingModule
],
declarations: [
AppComponent,
LoginComponent,
HomeComponent,
NewsfeedComponent,
TopBarComponent,
SideMenuComponent
],
providers : [
AuthGaurd
],
bootstrap: [
AppComponent
] })
export class AppComponent {}
home.component.ts
@Component({
selector: 'home',
moduleId: module.id,
templateUrl: 'home.component.html',
providers : [
LoginService
]
})
export class HomeComponent implements OnInit{
isLoggedin : boolean;
constructor (private loginService : LoginService) { }
ngOnInit(): void {
this.loginService.getLogged().subscribe((isLoggedIn: boolean) => {
this.isLoggedin = isLoggedIn;
}); }
}
home.component.html
<side-menu *ngIf='isLoggedin'></side-menu>
<top-bar *ngIf='isLoggedin'></top-bar>
<router-outlet></router-outlet>
auth.gaurd.ts
@Injectable()
export class AuthGaurd implements CanActivate{
constructor(private router : Router) {
}
canActivate(){
if (localStorage.getItem('isLogin')){
return true;
}
this.router.navigate(['/login'])
return false;
}
}
login.service.ts
@Injectable()
export class LoginService {
private subject: Subject<boolean> = new Subject<boolean>();
constructor(private router : Router) {
}
login(){
this.setLogged(true);
localStorage.setItem("isLogin","true");
this.router.navigate(['/news-feed']);
}
logout(){
this.setLogged(false);
localStorage.removeItem("isLogin");
this.router.navigate(['/login']);
}
getLogged(): Observable<boolean> {
return this.subject.asObservable();
}
setLogged(val : boolean): void {
this.subject.next(val);
}
}
login.component.ts
@Component({
selector: 'login',
moduleId: module.id,
templateUrl: 'login.component.html'
})
export class LoginComponent {
constructor (private loginService : LoginService) {
}
login(){
this.loginService.login()
}
}
login.component.html
<input type="number” #mobileNumber />
<input type="password" #password />
<input type="button" (click)="login()">
newsfeed.component.ts
@Component({
selector: 'newsfeed',
moduleId: module.id,
templateUrl: 'newsfeed.component.html',
})
export class NewsfeedComponent {
}
newsfeed.component.html
some html text....!!!!
app-routing.module.ts
@NgModule({
imports: [
RouterModule.forRoot([
{
path : 'login',
component : LoginComponent
},
{
path : 'news-feed',
component : NewsfeedComponent,
canActivate : [AuthGaurd]
},
{
path : '',
redirectTo : '/news-feed',
pathMatch : 'full'
}
{
path: '**',
component: LoginComponent
}
])
],
exports: [
RouterModule
]
})
export class AppRoutingModule {}
Actually it's working fine when i'm going with clicks. like its launching perfect than on click of login button it forwards to newsfeed and shows the expected result. but when I'm going from the browser url, its not loading side bar and top bar component from the home.html
回答1:
I'm not sure if this fixes everything but I think you want to read the value from localstorage first to get the recently stored status and if you use BehaviorSubject
listeners also get the last status if this.subject.emit()
was called before a subscriber was subscribing.
@Injectable()
export class LoginService {
//private subject: Subject<boolean> = new Subject<boolean>(false);
private subject: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(); // <<< changed
constructor(private router : Router) {
this.sublect.next(logalStorage.getItem('isLogin')); // <<< added
}
login(){
this.setLogged(true);
localStorage.setItem("isLogin","true");
this.router.navigate(['/news-feed']);
}
logout(){
this.setLogged(false);
localStorage.removeItem("isLogin");
this.router.navigate(['/login']);
}
getLogged(): Observable<boolean> {
return this.subject.asObservable();
}
setLogged(val : boolean): void {
this.subject.next(val);
}
}
回答2:
I encountered with that problem. Here is how I solve this situation;
- Create a shared service with observable fields as explained in official angular documents
- In your navigation bar component, subscribe to value from shared service to display navigation bar
- In login and logout pages, update value. Since you already subscribe the value, subscriber handle this situation by itself
- Create an authentication service. Add a method similar to this to ask your backend, is request authenticated;
//method parameters depend on what you want
isAuthorized(url: string, errorCallback: (any) => void) {
let body = JSON.stringify(url)
return this.http.post('account/isauthorized', body)
.map((response: Response) => {
//update value to display navigation bar if user is authenticated
yourSharedService.observableField.next(true);
return true;
})
.catch((response: Response) => {
errorCallback(response.status);
return Observable.of(false);
});
}
Create an authentication guard and call
isAuthorized
method incanActivate
orcanLoad
orCanActivateChild
.In your callback, handle unauthorized requests. You can redirect user to error pages or remove the navigation bar, and whatever you want.
I hope it helps!
来源:https://stackoverflow.com/questions/40523579/angular2-how-to-communicate-from-parent-component-to-child