Angular 4 Custom装饰器 - 注入服务

时间:2018-02-20 14:57:15

标签: angular typescript ecmascript-6

我想在我的应用程序中创建身份验证装饰器。

调用应该很简单

@RequireAuthentication()
@HostListener('click', ['$event']) onClick(event: Event) {
....
}

我知道装饰器只能起作用,所以在我计划的其他文件中

export function RequireAuthentication() {
    if (!userService.isAuthenticated) {
        navigationService.goToLogin();
        return;
    }
}

对我而言,问题是如何在这种情况下正确初始化userService和navigationService,因为这些服务包含用于查找用户是否经过身份验证并显示登录屏幕的所有逻辑。

我已经尝试过:

  1. 使用带构造函数的类进行服务初始化,但是嵌套方法不能用作装饰器
  2. 使用Injectable类来创建服务,我需要创建这个类的实例,同样的问题。
  3. 使用ModuleWithProviders方法隐藏身份验证实现并仅公开装饰器,但不确定这是否是正确的方法。
  4. 任何提示都会有所帮助。可能是我错过了一些基本的东西,因为我没有经验丰富的角色开发人员,或者有另一种方法可以解决这个问题。

    提前致谢!

1 个答案:

答案 0 :(得分:5)

正如this answer中所解释的那样,对于框架惯用的解决方案是公开injector类实例属性,因此可以在decorator中访问它。 injector属性的存在也​​可以通过接口保护。

由于属性装饰器运行一次并且可以访问类原型而不是实例,因此需要修补ngOnOnit方法并使用this.injector.get()在修补方法中检索所有必要的服务。

另一种方法是将全局注入器暴露给某个对象,如here所述。这不是惯用的解决方案,而是会导致某些限制和负面后果的黑客攻击。很难推荐用于生产。