首页 文章

如何在渲染角度组件时运行函数?

提问于
浏览
0

MyComponent使用服务获取数据然后呈现该数据 . 但是,在用户登录之前,服务无法获取数据 . 如果用户第一次进入路径'/ myPage',容器组件将显示登录组件 . 但是,即使呈现登录组件而不是ng-content(其评估为MyComponent),MyComponent也会通过angular和fetches进行初始化,并导致服务在登录之前过早地获取数据 . 因此,当用户成功登录时,MyComponent最后渲染,初始数据服务没有返回任何数据 .

如何在提取组件之后推迟数据提取?我已经在MyComponent中尝试了所有不同的生命周期方法但没有成功 .

app.component

<container>
    <router-outlet></router-outlet>
</container>

container component

<div *ngIf="!userService.getLoggedInUser()">
  <login></login>
</div>

<div *ngIf="userService.getLoggedInUser()">
  <ng-content></ng-content>
</div>

routing module

const routes: Routes = [
  { path: 'myPage', component: myComponent }
];

my component

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);

    }
  }

2 回答

  • 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' },
    

    这应该可以防止过早地路由到组件 .

    Route Resolver

    您可以考虑的另一个选项是使用路线解析器 . 它允许您在路由到特定组件之前检索路由的数据 .

    我不确定这会对您的情况有所帮助,但可能值得一看 .

    我在这里有一个例子:https://github.com/DeborahK/MovieHunter-routing

  • 0

    虽然这个问题肯定表明我的身份证明模式存在问题,但我想把这些发现留给任何偶然发现这个问题的人 .

    问题在于角度如何处理ngIf . ngIf内的组件始终“初始化”,无论它们是否显示 . 要防止此行为,请改用模板 .

    Angular4 ng-content gets built when ngIf is false

    话虽如此,即使使用模板,我的原始身份验证解决方案也不起作用,因为我无法将 <router-outlet> 嵌套到模板中 . 然后正确的解决方案是改变逻辑并使用DeborahK建议的路线防护 .

相关问题