MyComponent使用服务获取数据,然后呈现该数据。但是,在用户登录之前,服务无法获取数据。如果用户前往路线' / myPage'容器组件第一次将显示登录组件。但是,即使渲染登录组件而不是ng-content(其评估为MyComponent),MyComponent也会被angular和fetches初始化,并导致服务在登录之前过早地获取数据。因此,当用户成功登录时,MyComponent最后呈现,初始数据服务没有返回任何数据。
如何在呈现组件之前推迟数据提取?我在MyComponent中尝试了所有不同的生命周期方法但没有成功。
app.component
<container>
<router-outlet></router-outlet>
</container>
容器组件
<div *ngIf="!userService.getLoggedInUser()">
<login></login>
</div>
<div *ngIf="userService.getLoggedInUser()">
<ng-content></ng-content>
</div>
路由模块
const routes: Routes = [
{ path: 'myPage', component: myComponent }
];
我的组件
export class MyComponent {
data
constructor(private dataService: DataService) {}
ngOnInit () {
//how can i make run this service AFTER the component renders? i know
//ngOnInit is definitely not the correct lifecycle method, but what is?
this.dataService.get().then((data) => this.data = data);
}
}
答案 0 :(得分:2)
ngOnInit是用于检索组件数据的常规方法。所以,如果某些东西不起作用,我的猜测是其他地方存在问题。
Route Guard
例如,呈现登录对话框的一种常用方法是使用路由保护而不是ngIf。这看起来像这样:
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, RouterStateSnapshot, Router,
CanActivate } from '@angular/router';
import { AuthService } from './auth.service';
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService,
private router: Router) { }
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
return this.checkLoggedIn(state.url);
}
checkLoggedIn(url: string): boolean {
if (this.authService.isLoggedIn()) {
return true;
}
// Retain the attempted URL for redirection
this.authService.redirectUrl = url;
this.router.navigate(['/login']);
return false;
}
}
然后在需要登录的任何路线上使用此警戒:
{ path: 'welcome', component: WelcomeComponent },
{
path: 'movies',
canActivate: [AuthGuard],
loadChildren: './movies/movie.module#MovieModule'
},
{ path: '', redirectTo: 'welcome', pathMatch: 'full' },
这样可以防止过早地路由到组件。
路线解析器
您可以考虑的另一个选择是使用路线解析器。它允许您在路由到特定组件之前检索路由的数据。
我不确定这会对您的情况有所帮助,但可能值得一看。
答案 1 :(得分:0)
虽然这个问题肯定表明我的身份证明模式存在问题,但我想把这些发现留给任何偶然发现这个问题的人。
问题在于角度如何处理ngIf。 ngIf中的组件始终&#34;初始化&#34;无论是否显示。要防止此行为,请改用模板。
请参阅 Angular4 ng-content gets built when ngIf is false
话虽如此,即使使用模板,我的原始身份验证解决方案也不起作用,因为我无法将<router-outlet>
嵌套到模板中。正确的解决方案是改变逻辑,并使用DeborahK建议的路线保护。