12

Angular2 路由器 - 任何人都知道如何在 app.ts 中使用 canActivate 以便我可以在未登录的情况下重定向到主页

我正在使用打字稿和角度2。

在我的 app.ts 文件中我的构造函数下的当前尝试:

   canActivate(instruction) {           
               console.log("here - canActivate");
               console.log(instruction);

               this.router.navigate(['Home']);  
   }

它目前没有受到打击。知道为什么吗?

4

5 回答 5

12

所以文档看起来就像它导出的一样。

export CanActivate(options : CanActivateAnnotation) : (hook: (next: ComponentInstruction, prev: ComponentInstruction) =>
                     Promise<boolean>| boolean) => ClassDecorator

@CanActivate((next, prev) => {
      // This must prove to be true for the component @ this route to load
      if(next.urlPath != '/Login'){ 
         return Promise.resolve(this._authService.getIsAuth() 
         && localStorage.getItem('authToken')
      }
      /*
       If CanActivate returns or resolves to false, the navigation is 
       cancelled. If CanActivate throws or rejects, the navigation is also
       cancelled. If CanActivate returns or resolves to true, navigation 
       continues, the component is instantiated, and the OnActivate hook of 
       that component is called if implemented.
      */
   }
);

在 Angular2 文档的底部,他们添加了这个片段:从 angular2/router 导出 https://angular.io/docs/ts/latest/api/router/CanActivate-decorator.html

因此,如果您希望从更高级别进行重定向。您不会使用 CanActivate 装饰器,而是会执行以下操作。

import {Directive, Attribute, ElementRef, DynamicComponentLoader} from 'angular2/core';
import {Router, RouterOutlet, ComponentInstruction} from 'angular2/router';
import {Login} from '../login/login';
import {UserService} from '../../Services/userService'; // a service to handle auth

@Directive({
  selector: 'router-outlet'
})
export class AuthRouterOutlet extends RouterOutlet {
  publicRoutes: any;
  private parentRouter: Router;

  constructor(private _userService:UserService, _elementRef: ElementRef, _loader: DynamicComponentLoader,
              _parentRouter: Router, @Attribute('name') nameAttr: string) {
    super(_elementRef, _loader, _parentRouter, nameAttr);

    this.parentRouter = _parentRouter;
    this.publicRoutes = {
      '/login': true,
      '/signup': true
    };
    // publicRoutes will be the routes auth is not needed for.
  }

  activate(instruction: ComponentInstruction) {
    var url = this.parentRouter.lastNavigationAttempt;
    if (!this.publicRoutes[url] && this._userService.getAuth()) {
      // todo: redirect to Login, may be there a better way?
      this.parentRouter.navigateByUrl('/login');
    }
    return super.activate(instruction);
    // we return super.activate(instruction) here so the router can activate the requested route and it's components.
  }
}

此实现处理对指令的任何新请求,并在您的路由身份验证逻辑所在的位置运行激活函数。上面的代码将被称为 AuthRouterOutlet。你必须通过将它添加到你的 app.ts

directives: [ AuthRouterOutlet]
于 2016-01-13T05:49:45.437 回答
5

使用路由器的新测试版,您还可以在此处查看我关于如何使用 CanActivate 接口的答案:

https://stackoverflow.com/a/38369948/1944351

使用其他答案中提到的装饰器也很好。

于 2016-07-14T09:08:16.717 回答
2

自 22/6/16 起,这些答案在 RC 候选人中不再有效。

有很多关于@CanActivate注释的新解决方案的讨论,但您可以在过渡期间恢复使用该angular-2/router-deprecated版本。

如果你想关注这个领域的更新,如果你想使用较新的路由器实现,请查看这两个 github 问题:

抱歉,目前没有完整的答案,如果我看到这方面的任何进一步进展,我将更新此回复。我也在寻找一个优雅的解决方案。

在此期间,我只是ngIf='fooObject'在 div 中使用 a 来检查子指令中使用的对象是否已填充/真实,然后渲染其余组件 html。这并不理想,但它现在确实可以始终如一地工作。取决于您的用例,可能会对您有所帮助或不帮助。我不需要重定向,只需检查我的数据是否已解析以显示我的组件。

于 2016-06-21T22:27:44.013 回答
1

从这里:

https://angular.io/docs/ts/latest/api/router/CanActivate-decorator.html

CanActivate是注解,不是函数。你像这样使用它:

@Component({selector: ... })
@CanActivate(()=>console.log('Should the component Activate?'))
class AppComponent {

}

routerOnActivate是您在组件中使用的函数:

https://angular.io/docs/ts/latest/api/router/OnActivate-interface.html

于 2016-01-12T21:56:30.177 回答
0

@CanActivate 已被删除。在此处查看更多详细信息。

您现在应该使用route.canActivate

于 2017-05-13T21:16:15.043 回答