【问题标题】:Instantiate Class constant with dependency injection使用依赖注入实例化类常量
【发布时间】:2017-11-11 23:17:37
【问题描述】:

我们使用角度常量来定义类。我怎样才能使一个类常量在实例化时可以在构造函数中有一个参数但也有依赖注入?我的思路是这样的:

ClassA.js

class ClassA { ... }

angular.module("myApp").constant("ClassA", ClassA);

ClassB.js

class ClassB {
  constructor(constrParams, ClassA) { // mix of constructor parameter and DI
    this.constrParams = constrParams;
    this.ClassA = ClassA;
  }
}

ClassB.$inject = ["ClassA"]; // ClassB needs reference to ClassA
angular.module("myApp").constant("ClassB", ClassB);

在另一个常量中导入 ClassB 时我仍然可以这样做吗

ClassC.js

class ClassC {
  constructor(ClassB) {
    this.classBinst = new ClassB("myparams"); // instantiate new ClassB instance
  }
}

ClassC.$inject = ["ClassB"];
angular.module("myApp").constant("ClassC", ClassC);

【问题讨论】:

    标签: javascript angularjs ecmascript-6 constants es6-class


    【解决方案1】:

    如果你想手动传递任何构造函数参数,我认为你必须手动传递它们。

    所以ClassC 也必须将ClassA 作为参数传递给ClassB

    class ClassC {
      constructor(ClassB, ClassA) {
        this.classBinst = new ClassB("myparams", ClassA); // instantiate new ClassB instance
      }
    }
    

    但是,如果您创建需要ClassCClassD,您就会遇到同样的问题——需要传入ClassC 及其所有依赖项(ClassBClassA)。

    但是如果ClassC 是最后一层并且可以作为单例实例化和注入,那么您可以创建一个实例化ClassC 的服务,而无需担心它的依赖关系:

    angular.module("myApp").service('instanceC', ClassC);
    
    angular.module("myApp").controller('myController', function (instanceC) {
        // Everything has been resolved
    });
    

    也许您最好创建一个服务来为您创建这些类的实例。该服务可以解决类所需的依赖关系并手动传递它们,而控制器可以传递任何自定义参数:

    class factory {
        constructor(ClassA, ClassB, ClassC) {
            this.ClassA = ClassA;
            this.ClassB = ClassB;
            this.ClassC = ClassC;
        }
    
        createB(customParamForClassB) {
            return new this.ClassB(customParamForClassB, this.ClassA)
        }
    }
    
    angular.module("myApp").service('factory', factory);
    
    angular.module("myApp").controller('myController', function (factory) {
        let instanceB = factory.createB('myparams');
    });
    

    【讨论】:

    • 我扩展了您的想法并使用了工厂。这提供了实际的类定义来实例化,而不是在依赖注入时显式创建函数
    【解决方案2】:

    我扩展了 Frank 将类作为服务提供的想法,但改用了工厂构造。工厂提供了可以直接实例化的类定义,而不是服务中的显式创建函数。模式如下:

    ClassA.js

    class ClassA { ... }
    
    angular.module("myApp").factory("ClassA", () => ClassA);
    

    ClassB.js

    class ClassB {
      constructor(constrParams) {
        this.constrParams = constrParams;
        // this.ClassA reference is already injected through factory
      }
    }
    
    angular.module("myApp")
    .factory("ClassB", ["ClassA", (ClassA) => {
      // this is where dependency injection happens
      ClassB.prototype.ClassA = ClassA;
      return ClassB; // class definition
    }]);
    

    ClassC.js(最终目标 - 与之前相同)

    class ClassC {
      constructor() {
        // instantiate new ClassB instance
        this.classBinst = new this.ClassB("myparams");
      }
    }
    
    angular.module("myApp").factory("ClassC", ["ClassB", (ClassB) => {
      ClassC.prototype.ClassB = ClassB;
      return ClassC;
    }]);
    

    相关模式:Correct way of wrapping javascript class in AngularJS module and inject angular services

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-10-13
      • 2014-02-28
      • 2019-11-23
      • 2018-01-15
      • 1970-01-01
      • 2013-03-08
      • 2018-02-11
      相关资源
      最近更新 更多