【问题标题】:Angular Injected fail when add custom class decorator添加自定义类装饰器时,Angular Injected 失败
【发布时间】:2018-01-12 01:07:33
【问题描述】:

根据tutorial,我尝试实现自定义装饰器,允许我们根据用户角色限制对组件类的访问。否则重定向到其他组件(我知道它有其他策略来归档它,但它不适合我们的用例)。

它按我的方式工作,但只有当我在本地机器上运行而不是在部署服务器上运行时。错误就像它不能在使用这个装饰器的每个组件的构造函数中注入任何服务或类???

role-required.decorator.ts

export function RoleRequired(roles: string[], redirectUrl = '/forbidden') {

    return function<T extends {new(...args:any[]):{}}> (constructor:T) {

        // save a reference to the original constructor
        const original = constructor;

        // a utility function to generate instances of a class
        function construct(constructor, args) {
            const c : any = function () {
                return constructor.apply(this, args);
            };
            c.prototype = constructor.prototype;
            return new c();
        }

        // the new constructor behaviour
        const f : any = function(router: Router, ...args) {
            console.log("Class: " + original.name);
            this.__verifyRole = JSON.parse(localStorage.getItem("roles")) || [];

            const that = this;
            const isGrant = roles.every((item, index) => {
                return that.__verifyRole.indexOf(item) != -1
            });

            if (!isGrant) {
                router.navigate([redirectUrl]);
            }

            return construct(original, args);
        };

        // copy prototype so intanceof operator still works
        f.prototype = original.prototype;

        // copy metadata to new constructor
        let metadatakeys = Reflect.getMetadataKeys(constructor);
        metadatakeys.forEach(function (key) {
            Reflect.defineMetadata(key, Reflect.getOwnMetadata(key, constructor), f)
        });

        // read dependencies list from 'cls', add our own dependency, and write list to 'newCls'
        let dependencies = Reflect.getOwnMetadata('design:paramtypes', constructor);
        dependencies = [Router].concat(dependencies);
        Reflect.defineMetadata('design:paramtypes', dependencies, f);

        // return new constructor (will override original)
        return f;
    }
}

先决条件

app.module.ts 导入此类 导入“反射元数据”;

用法

@RoleRequired(['role.user.chat'])
export class ChatRoomComponent {}

错误信息是启动组件时注入类的所有属性。

错误类型错误:无法读取属性“informSoundSettingChange” 未定义

package.json

{
  "name": "alpha-love-chat-ng",
  "version": "1.0.0",
  "license": "MIT",
  "angular-cli": {},
  "scripts": {
    "ng": "ng",
    "start": "ng serve --deploy / --proxy-config proxy.conf.json",
    "build": "ng build --prod --aot output-hashing none --deploy /",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "^4.2.6",
    "@angular/cdk": "^2.0.0-beta.8",
    "@angular/common": "^4.2.6",
    "@angular/compiler": "^4.2.6",
    "@angular/core": "^4.2.6",
    "@angular/forms": "^4.2.6",
    "@angular/http": "^4.2.6",
    "@angular/material": "^2.0.0-beta.8",
    "@angular/platform-browser": "^4.2.6",
    "@angular/platform-browser-dynamic": "^4.2.6",
    "@angular/router": "^4.2.6",
    "angular-datatables": "^4.1.1",
    "angular2-notifications": "^0.7.4",
    "angular2-uuid": "^1.1.1",
    "bootstrap": "^3.3.7",
    "core-js": "^2.4.1",
    "datatables.net": "^1.10.15",
    "datatables.net-dt": "^1.10.15",
    "howler": "^2.0.4",
    "jquery": "^3.2.1",
    "lz-string": "^1.4.4",
    "malihu-custom-scrollbar-plugin": "^3.1.5",
    "moment": "^2.18.1",
    "moment-timezone": "^0.5.13",
    "ng2-modal": "0.0.25",
    "ngx-facebook": "^2.4.0",
    "ngx-infinite-scroll": "^0.5.1",
    "reflect-metadata": "^0.1.10",
    "rxjs": "^5.4.2",
    "rxjs-extra": "^0.1.1",
    "signalr": "^2.2.2",
    "underscore": "^1.8.3",
    "zone.js": "^0.8.4"
  },
  "devDependencies": {
    "@angular/cli": "^1.2.0",
    "@angular/compiler-cli": "^4.2.6",
    "@angular/language-service": "^4.2.6",
    "@types/bootstrap": "^3.3.34",
    "@types/datatables.net": "^1.10.4",
    "@types/howler": "^2.0.2",
    "@types/jasmine": "2.5.45",
    "@types/jquery": "^3.2.6",
    "@types/lz-string": "^1.3.32",
    "@types/moment": "^2.13.0",
    "@types/moment-timezone": "^0.2.34",
    "@types/node": "^6.0.80",
    "codelyzer": "~3.0.1",
    "jasmine-core": "~2.6.2",
    "jasmine-spec-reporter": "~4.1.0",
    "karma": "~1.7.0",
    "karma-chrome-launcher": "~2.1.1",
    "karma-cli": "~1.0.1",
    "karma-coverage-istanbul-reporter": "^1.2.1",
    "karma-jasmine": "~1.1.0",
    "karma-jasmine-html-reporter": "^0.2.2",
    "protractor": "~5.1.2",
    "ts-node": "~3.0.4",
    "tslint": "~5.3.2",
    "typescript": "~2.3.3"
  }
}

【问题讨论】:

  • 错误是什么?你在使用 AOT 吗?
  • 是的,我正在使用 AOT,错误是每个服务类的属性未定义。
  • 说真的,我担心这是一个 AOT 限制......我猜它会在构建时创建注入逻辑,所以你不能在启用 AOT 的情况下使用你的装饰器......
  • 好的,我会尝试删除它并测试。
  • @n00dl3 remove --aot 仍然无法正常工作同样的错误

标签: angular angular-decorator


【解决方案1】:

根据@n00dl3 在评论中的建议..

说真的,我担心这是 AOT 限制......我猜它会创建 在构建时注入逻辑,因此您不能将装饰器与 AOT 一起使用 启用..

但是,我尝试过,起初它不起作用,因为..

"ng build --prod --aot output-hashing none --deploy /"

我只是删除了--aot,但我仍然有这个标志--prod,默认情况下它将启用--aot true,所以我通过--aot false修复github.com/angular/angular-cli/wiki/build

最终版

"ng build --prod --aot false output-hashing none --deploy /"

而不是

"ng build --prod output-hashing none --deploy /"

总之 remove --aot 标志解决了我的问题,防止它删除我的自定义装饰器。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-06
    • 2019-03-29
    • 2021-12-25
    • 1970-01-01
    • 2018-07-30
    • 2019-08-04
    • 2013-10-25
    相关资源
    最近更新 更多