【问题标题】:Angular6 app logic that runs on every page在每个页面上运行的 Angular6 应用程序逻辑
【发布时间】:2019-01-15 23:54:16
【问题描述】:

我目前正在从 AngularJS 转换为 Angular6,但没有找到任何解决此问题的方法。

将需要在 Angular 应用加载的每个页面上运行的应用逻辑保留在哪里的最佳做法是?

示例逻辑是根据存储在机器上的 cookie 登录用户。我应该把这个逻辑放在哪里来检查 cookie 并让用户登录?

到目前为止我见过的最好的地方是app.component.ts。我曾经在 AngularJS 中通过在所有页面上加载 GlobalController 来完成此操作,然后加载 HomepageController 等,这将为插入页面的特定“部分”加载。

e/ 澄清一下,这只是一个示例,并不是我需要在每个页面上运行的唯一业务逻辑。我需要每隔约 10 秒触发一次后端请求,以检查服务器上的计时器(用于应用程序超时/等)。

【问题讨论】:

  • 好问题!好吧,我认为这取决于您要执行哪些共享操作...例如,正如您所说,我一直将共享逻辑保留在app.component 中-这是放置始终运行逻辑的最佳位置。但是对于 cookie 检查或类似的问题,我总是将所有检查方法放在service 中。当然,如果它需要一直运行,我会在应用组件上调用它

标签: angular components global angular6


【解决方案1】:

你应该把这个逻辑放在 app.components.ts

import { Component } from "@angular/core";

@Component({
    selector: "app-root",
    templateUrl: "./app.component.html",
    styleUrls: ["./app.component.css"]
})
export class AppComponent {
    // here goes your logic
}

【讨论】:

  • 不,你不应该。这是一个不好的做法。也许对于个人项目来说,这没什么大不了的。如果您正在从事专业项目,则不应这样做。
【解决方案2】:

为了验证 Http 请求,您可以HttpInterceptors 为您的 API 的每个请求附加一个令牌。像这样 ->

my-http.interceptor.ts

 @Injectable()
 export class MyHttpInterceptor implements HttpInterceptor {

   constructor() {}

      intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
         const token = 'my_token'; // retrieve token from your storage.
         const req = request.clone({
             setHeaders: {
               Authorization: `Bearer ${token}`
             }
           });

           return next.handle(req).do((event: HttpEvent<any>) => {
             // success
             if (event instanceof HttpResponse) {
             }
           }, (err: any) => {
             // failure
             if (err instanceof HttpErrorResponse) {
             }
           });
       }
 }

然后在您的 CoreModule 或 AppModule 上注册您的 http 拦截器。

 providers: [
     { provide: HTTP_INTERCEPTORS, useClass: MyHttpInterceptor, multi: true}
 ]

RouteGuards 可用于以任何您想要的原因阻止某些路由 - 用户未获得授权,用户没有适当的角色来访问,等等...

https://codecraft.tv/courses/angular/routing/router-guards/


如果你想在路由更改上执行逻辑,你可以监听 router.events。

How to detect a route change in Angular?


编辑: 正如该线程中的其他人所指出的,始终将业务逻辑放在服务中。

关于最佳实践 Angular 应用程序结构 -> https://itnext.io/choosing-a-highly-scalable-folder-structure-in-angular-d987de65ec7

【讨论】:

    【解决方案3】:

    您可以在您的应用程序中创建一个身份验证服务 (auth.service.ts) 并使其成为单例,该服务将包含所有身份验证操作,例如(登录、注销、getProfile...),之后您可以注入该服务并需要时在您的应用中随处使用它。

    我建议您将您的应用程序分成模块并创建一个模块进行身份验证。

    对于所有共享的内容,您可以创建一个包含共享组件、服务、管道、拦截器的共享模块...

    【讨论】:

      【解决方案4】:

      我会使用 Angular service,我会从 app.component 调用它

      它说

      服务是在不提供服务的类之间共享信息的好方法 互相认识。

      【讨论】:

        【解决方案5】:

        这是一个使用 AuthenticationService 和 CanActivate 路由保护来解决您的特定问题的示例。下面的Guard可以绑定到你喜欢的任何路由(页面),无论是其中一个还是全部。

        @Injectable()
        class AuthenticationService {
          constructor () { }
        
          isLoggedIn() {
            // check your cookie logic here
          }
        }
        
        @Injectable()
        class AuthenticationGuard implements CanActivate {
        
          constructor(private authenticationService: AuthenticationService, private router: Router) { }
        
          canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
            return this.authenticationService.isLoggedIn()
              .pipe(
                tap(loggedIn => {
                  if (!loggedIn) {
                    this.router.navigate(['/login'], {
                      queryParams: {
                        nextUrl: state.url
                      }
                    });
                  }
                })
              );
          }
        }
        
        @NgModule({
          ...
          imports: [
            RouterModule.forRoot([
              { path: 'dummyRoute/', loadChildren: './components/dummyModule/dummy.module#DummyModule', canActivate: [ AuthenticationGuard ] },
            ])
          ],
          ...
        })
        export class AppModule {}

        虽然使用 AppComponent 在每个页面上运行代码是一种解决方案,但我只推荐它作为最后的手段。在大多数情况下,Guards(用于授权导航步骤)、Resolvers(用于检索页面之前加载所需的数据)和 Interceptors(用于更改/过滤 HttpClient 请求)与 Services 一起使用为您提供了一种更优雅的方式来解决这些问题并保持您的代码库井井有条。

        更多关于守卫的信息在这里https://angular.io/guide/router#guards

        身份验证保护实现的完整示例:https://angular.io/guide/router#canactivate-requiring-authentication

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-04-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-04-20
          • 2014-03-07
          • 1970-01-01
          • 2015-12-15
          相关资源
          最近更新 更多