【问题标题】:How to handle closures in TypeScript (Angular injections)?如何处理 TypeScript 中的闭包(Angular 注入)?
【发布时间】:2016-04-22 01:16:34
【问题描述】:

我在 JavaScript 中有一个 Angular 工厂服务,我这样定义:

app.service('MyServiceFactory', ['$http', '$timeout', '$interval',
  function($http, $timeout, $interval) {

  function MyService() {
    // I can use all injected values here without additional efforts
  }

  this.Create = function() {
    return new MyService();
  }

}]);

现在我想把它转换成 TypeScript:

module Services {

  export class MyServiceFactory {
    static $inject: string[] = ['$timeout', '$interval', '$http'];

    constructor(
      private timeout: angular.ITimeoutService,
      private interval: angular.IIntervalService,
      private http: angular.IHttpService) {
    }
    public create(): MyService { return new MyService(); };
  }

  export class MyService() {
    // I have a problem here. I need to redefine and
    // initialize all variables, injected into my factory class
  }

  angular.module('MyModule').service('MyServiceFactory', MyServiceFactory);
}

你明白我的意思吗? TypeScript 不允许嵌套类,这可以解决问题。此外,TypeScript 解决方案看起来很不酷。有没有更优雅的解决方案?

【问题讨论】:

    标签: javascript angularjs typescript closures


    【解决方案1】:

    代替:

    export class MyService() {
        // I have a problem here. I need to redefine and
        // initialize all variables, injected into my factory class
      }
    

    您可以将Create 放在MyServiceFactory 上,即:

    module Services {
    
      export class MyServiceFactory {
        static $inject: string[] = ['$timeout', '$interval', '$http'];
    
        constructor(
          private timeout: angular.ITimeoutService,
          private interval: angular.IIntervalService,
          private http: angular.IHttpService) {
        }
        public create(){ 
          // Use the revealing module pattern 
          // And let the compiler infer the return type
          // e.g.
          var foo = 23;
          return {
             foo
          }
        };
      }
    
      angular.module('MyModule').service('MyServiceFactory', MyServiceFactory);
    }
    

    请注意,有效的 JavaScript 是有效的 TypeScript (more)

    【讨论】:

      【解决方案2】:

      您可以将注入的变量作为参数传递给您的其他类,例如:

      export class MyServiceFactory {
        static $inject: string[] = ['$timeout', '$interval', '$http'];
      
        constructor(
          private timeout: angular.ITimeoutService,
          private interval: angular.IIntervalService,
          private http: angular.IHttpService) {
      
        }
      
        public create(): MyService {
          return new MyService(this.timeout, this.interval, this.http);
        }
      }
      
      export class MyService {
        constructor(
          private timeout: angular.ITimeoutService,
          private interval: angular.IIntervalService,
          private http: angular.IHttpService) {
          // no more problems here, you can play with the injected variables again
        }
      }
      
      angular.module('MyModule').service('MyServiceFactory', MyServiceFactory);
      

      【讨论】:

      • 这正是我想要避免的。看看 TypeScript 代码是如何几乎是我最初的 JavaScript 解决方案的三倍?
      • 请注意,您不需要另一个类来返回 create。你总是可以使用 create 返回你想要的对象,或者你甚至可以在你的类中创建一个方法来返回你想要的。
      • 事实上,你甚至可以使用你当前的 Javascript 方法并且只实现类型,你根本不需要使用 ES6 类。毕竟,TypeScript 是带有类型的 Javascript。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-19
      • 2020-07-20
      • 2015-08-28
      • 2017-01-15
      • 2014-09-26
      相关资源
      最近更新 更多