【问题标题】:Add a decorator to an angularjs directive with typescript使用 typescript 向 angularjs 指令添加装饰器
【发布时间】:2016-08-05 12:38:48
【问题描述】:

我为 ComponentInject 创建了自己的打字稿装饰器,它看起来像这样

@Component(myModule, {
  selector: 'selector',
  templateUrl: 'template.html',
  bindings: {
    value: '=',
  },
})
@Inject('service')
export class ComponentController {
  value: string;

  constructor(private service: Service) {}
}

装饰器代码在哪里

export const Component = function(moduleOrName: string | ng.IModule, options: any): Function {
  return (controller: Function) => {
    let module = typeof moduleOrName === 'string' ? angular.module(moduleOrName) : moduleOrName;
    let component = angular.extend(options, { controller });
    module.component(options.selector, component);
  };
};

export const Inject = function(...injections: string[]): Function {
  return (target: Function) => {
    target.$inject = injections;
    return target;
  };
};

它工作正常,现在我想对需要使用 compilelink 函数但我无法使其工作的指令做同样的事情

@Directive(app, {
  selector: 'selector',
  templateUrl: 'template.html',
  scope: {
    value: '=',
  },
})
@Inject('service')
export class myDirective implements ng.IDirective {
  value: string;

  constructor(private service: Service) {}

  compile(element: ng.IAugmentedJQuery) {
    return this.service.compile(element);
  }
}

指令装饰器的代码是

export const Directive = function(moduleOrName: string | ng.IModule, options: any): Function {
  return (directive: Function) => {
    let module = typeof moduleOrName === 'string' ? angular.module(moduleOrName) : moduleOrName;
    let prueba = angular.extend(options, { directive })
    module.directive(options.selector, prueba);
  };
};

当我创建指令时,它总是在角度库中显示这个错误

参数 'fn' 不是函数,得到了对象

可以通过装饰器完成,还是我应该忘记它并按照通常的方式进行?

谢谢。

【问题讨论】:

  • 另外,options.selector 不会像你期望的那样工作,因为它没有被规范化。需要注意的是,控制器已经有了$postLink钩子,编译可以替换为template函数用于内联模板。
  • @estus 我不明白,我应该在哪里写你的代码?在return (directive: Function) 里面?还有new directive(...args) 在做什么?它显示一个错误。
  • 其实还是写成let factory = (...args) => { let prueba = angular.extend(options, new directive(...args)); return prueba }; factory.$inject = directive.$inject; module.directive(options.selector, factory)比较好。 directive 这里是一个指令对象的class,是你把它命名为directive。而factory 是返回指令对象的工厂函数。 module.directive 接受工厂函数作为参数,如果类构造函数没有用工厂包装,则可能会抛出。
  • 这是由angular.extend 造成的,它没有复制原型道具。它应该是angular.extend(new directive(...args), options)。除了 selector 之外的任何道具在装饰器中都是多余的 - TS 类已经具有属性。
  • 您的指令类遇到了问题 - 看起来您希望为每个指令实例创建一个实例 (value prop)。这不是真的。 DDO 对象将被创建一次,并将在所有实例之间共享。您可以将注入的 deps 存储在 this 中,但您不能在其中存储范围值 - 它们将被不同的指令实例覆盖。组件是完全不同的情况,this 是那里的控制器实例。您也可以查看this 以供参考。

标签: angularjs angularjs-directive typescript decorator


【解决方案1】:

应该是

export const Directive = function(moduleOrName: string | ng.IModule, selector: string): Function {
    return (directive: any) => {
        let module = typeof moduleOrName === 'string' ? angular.module(moduleOrName) : moduleOrName;
        let factory = (...args: any[]) => {
            let options = {
                controller: function () {},
            };
            return angular.extend(new directive(...args), options);
        };
        factory.$inject = directive.$inject;
        module.directive(selector, factory);
    };
};

@Directive(app, 'selector')
@Inject('service')
export class MyDirective implements ng.IDirective {
    templateUrl = 'template.html';
    scope = {
        value: '=',
    };
    constructor(private service: Service) {}
    compile = function(element: ng.IAugmentedJQuery) {
        return this.service.compile(element);
    }
}

【讨论】:

    猜你喜欢
    • 2016-04-13
    • 1970-01-01
    • 2021-03-11
    • 2019-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-23
    相关资源
    最近更新 更多