Angular 2:将依赖项注入@CanActivate?

时间:2016-01-10 23:19:59

标签: angular angular2-routing

在Angular 2中,您可以为组件指定@CanActivate注释,您可以在其中确定是否应激活组件。它不是接口的原因是因为在组件被实例化之前调用了回调。问题是,我无法找到一种方法来将依赖注入到该回调中。我需要我的服务,告诉我我是否登录(以及作为谁)以确定是否允许路由到特定组件。

如何将依赖注入@CanActivate回调?我正在使用ES5,但这不起作用:

app.ListsComponent = ng.router.CanActivate([
    app.SessionService,
    function(session, instruction) {
        console.log(session);
        return true;
    }
])(app.ListsComponent);

编辑:或者,我可以在组件上使用routerOnActivate生命周期事件,并使用this.router.navigate将用户送去,如果他们不应该在那里。缺点是它会破坏浏览器历史记录:如果每次到达特定URL时我都会异步重定向您,则无法在浏览器中非常有用地使用“后退”按钮。有没有办法让router.navigate使用history.replaceState代替history.pushState来解决这种情况?

5 个答案:

答案 0 :(得分:7)

此处的大多数解决方案都会出现从层次结构中的其他位置加载子依赖项的问题,因为它们会创建新的注入器。此外,这会导致实例化其他(非共享)服务。我建议遵循Brandon在https://github.com/angular/angular/issues/4112

中提供的模式

他引用了这个Plunk:http://plnkr.co/edit/SF8gsYN1SvmUbkosHjqQ?p=preview

它的主要思想是单例注入器,他在应用初始化时保存。这提供了对您已配置的根依赖项的访问,并进一步允许您的服务作为单个用户共享,因为它们可能是:

import {Injector} from 'angular2/angular2';
let appInjectorRef: Injector;

export const appInjector = (injector?: Injector):Injector => {
    if (injector) {
      appInjectorRef = injector;
    }

    return appInjectorRef;
};

bootstrap([ServiceYouNeed]).then((appRef) => {
    // store a reference to the injector
    appInjector(appRef.injector);
});

答案 1 :(得分:2)

你必须使用注射器注射它。 只是从我正在做的项目中快速复制粘贴:

'latex'

如果您的服务是在构造函数中注入HTTP服务,则必须传递HTTP_PROVIDERS。

我用它来观察下一个物体的参数。下一个对象是您的下一个“组件/状态”:

@CanActivate((next: ComponentInstruction, prev: ComponentInstruction) => {

  console.info('CanActivate hook! - can return boolean or Promise');

  var injector = Injector.resolveAndCreate([HTTP_PROVIDERS, YourService]);
  var yourService = injector.get(YourService);
  // do something with yourService
  return new Promise(function(resolve, reject) {
      resolve(true);
  });

})

PropertiesService调用后端并返回一个Observable,它表示具有属性

的数据

答案 2 :(得分:1)

我不知道它是否是最好的方式,但这些人通过扩展和使用自己的<router-outlet>并覆盖CanActivate方法来实现:

https://auth0.com/blog/2015/05/14/creating-your-first-real-world-angular-2-app-from-authentication-to-calling-an-api-and-everything-in-between/

您也可以使用routerOnActivate

https://angular.io/docs/js/latest/api/router/OnActivate-interface.html 我希望这有帮助。

答案 3 :(得分:1)

这里(https://gist.github.com/clemcke/c5902028a1b0934b03d9)是如何测试@shannon引用的addInjector()解决方案:

beforeEachProviders(()=>[PERSON_SERVICE_PROVIDERS]);

beforeEach(inject([PersonService],()=>{
  let injector = Injector.resolveAndCreate([PERSON_SERVICE_PROVIDERS]);
  appInjector(injector);
}));

答案 4 :(得分:0)

Angular 2.0最终解决方案:

由于我们现在定义了一个实现CanActivate的单独类,该类可以是@Injectable,并且可以根据this answer在其构造函数中提供另一个依赖项。

相关问题