angularjs 1.8和es6模块:如何使服务或工厂“通过”基于类的api接口?

twh00eeo  于 2021-09-29  发布在  Java
关注(0)|答案(1)|浏览(362)

我正在逐步改进一个代码库,它最初在不同版本中有一些angularjs,而一些代码根本不在使用不同版本的软件api的框架中(出于某种原因,这个api在angularjs上是可用的——通过应用程序加载的页面 $window.external …想想看。)
在es6之前的angularjs 1.8阶段,我有三个与软件api交互的服务(调用它们) someAPIget , someAPIset ,及 someAPIforms ). 大概是这样的:

// someAPIget.service.js 
;(function () {
  var APIget = function ($window, helperfunctions) {
  function someFunc (param) {
    // Do something with $window.external.someExternalFunc
    return doSomethingWith(param)
    }
  return {
    someFunc: someFunc
    }
  }
  angular.module('someAPIModule').factory('someAPIget', ['$window', 'helperfunctions', someAPIget])
})()

然后我有了一个服务模块和一个更高级别的模块 someAPIModule 作为依赖项,它聚合这些函数并以一个名称传递它们,如下所示:

// apiinterface.service.js 
;(function () {
  // Change these lines to switch which API service all functions will use.
  var APIget = 'someAPIget'
  var APIset = 'someAPIset'
  var APIforms = 'someAPIforms'
  var APIInterface = function (APIget, APIset, APIforms) {
    return {
      someFunc: APIget.someFunc,
      someSettingFunc: APIset.someSettingFunc,
      someFormLoadingFunc: APIforms.someFormLoadingFunc
    }
  }
  angular.module('APIInterface').factory('APIInterface', [APIget, APIset, APIforms, APIInterface])
})()

然后,我将使用 APIInterface.someFunc(etc) . 它工作得很好,如果我们切换到不同的软件供应商,我们可以使用相同的页面,而无需重写所有内容,只需重写接口逻辑。
然而,我正在尝试升级到typescript和es6,这样我就可以使用导入和导出,并构建一些可以通过命令行访问的逻辑,另外,当我准备好升级到angular 11或任何最新版本时,还要准备升级到angular 11。所以我重新构建了一个类:

// someAPIget.service.ts
export class someAPIget {
  private readonly $window
  private readonly helperfunctions
  static $inject = ['$window', 'helperfunctions']

  constructor ($window, helperfunctions) {
    this.$window = $window
    this.helperfunctions = helperfunctions
    }

  someFunc (param) {
    // Do something with this.$window.external.someExternalFunc
    return doSomethingWith(param)
    }
  }
}

angular
  .module('someAPImodule')
  .service('someAPIget', ['$window', 'helperfunctions', someAPIget])

起初,它似乎是有效的(我的测试仍然通过,或者至少在typescript编译部门进行了一点清理之后通过),但当我将其加载到live应用程序中时。。。 this.$window 没有定义。但是,如果我使用直接依赖项并调用 someAPIget.someFunc(param) 而不是通过 APIInterface.someFunc(param) 它工作得很好(但我真的不想使用apiinterface为调用重写数千行代码,另外,它还将讨论在接口中 Package 它的全部意义)。我曾尝试将apiinterface制作成一个类,并为每个返回导入函数的函数分配getter,但是 $window 仍然没有定义。使用console.log语句,我可以看到 this.$window 定义在 someFunc 它是在API接口的getter中定义的,但是从我尝试使用 APIInterface 它调用它时没有首先在上运行构造函数 someAPIget ,即使我确保使用 $onInit() 有关电话。
我觉得我错过了一些简单的东西。是否有某种方法可以正确地聚合和重命名这些函数,以便在整个程序中使用?如何将它们正确地别名到后期构造的版本?
编辑以添加:我尝试将someapiget作为工厂和服务,将apiinterface作为工厂和服务,并在中调用apiinterface .run() 整体 app.module.ts 文件,但这些文件都不起作用(最后一个只是更改未定义错误的位置。)
再次编辑:我也尝试过使用 static 对于这种情况,这显然是错误的,但至少我在的vscode中得到了有用的错误提示 Property 'someProp' is used before its initialization.ts(2729) .
您应该如何确切地使用构造函数中指定的属性?在尝试访问类的成员之前,如何强制angularjs执行构造函数?

zdwk9cvp

zdwk9cvp1#

我根本不相信我找到了一个最佳或“正确”的解决方案,但我确实找到了一个有效的解决方案,我将在这里分享,以防它对其他人有所帮助。
最后,我在apiinterface类上用同名的类方法调用了每个导入的函数,如下所示:

// apiinterface.service.ts 
// Change these lines to switch which API service all functions will use.
const APIget = 'someAPIget'
const APIset = 'someAPIset'
const APIforms = 'someAPIforms'

export class APIInterface {
  private readonly APIget
  private readonly APIset
  private readonly APIforms

  constructor (APIget, APIset, APIforms) {
    this.APIget = APIget
    this.APIset = APIset
    this.APIforms = APIforms
  }

  someFunc(param: string): string {
    return this.APIget.someFunc(param)
  }
  someSettingFunc(param: string): string {
    return this.APIset.someSettingFunc(param)
  }
  someFormLoadingFunc(param: string): string {
    return this.APIforms.someFormLoadingFunc(param)
  }

}

angular
  .module('APIInterface')
  .factory('APIInterface', [APIget, APIset, APIforms, APIInterface])

我觉得这很讨厌,但确实管用。

相关问题