javascript - 访问一个可能存在也可能不存在的 Angular 服务

标签 javascript angularjs

我目前正在开发一个非常模块化的 Angular 项目 - sections of the app can be enabled and disabled for different clients using Webpack.到目前为止,这种结构对我来说效果很好,但我遇到的一个问题是如何处理可能并不总是存在的服务。

我当前的解决方案非常简单 - 我使用 $injector.has() 检查服务当前是否存在,如果存在,我使用 $injector.get() 获取它:

function initialize($injector) {
    if ($injector.has("barcode")) {
        let barcode = $injector.get("barcode");

        // Do stuff with the barcode service
    }
}

这似乎行得通 - 但是,我找不到有关此模式的使用以及它是否有任何潜在缺点的太多信息。

所以,我的问题是:

  • 以这种方式使用注入(inject)器有什么我应该注意的注意事项吗?
  • 是否有更好/更惯用的方法来做到这一点?

最佳答案

这可能是完成您想要的事情的最佳方式;但是,在执行此操作时,请注意您正在从 Dependency Injection 移动 (DI) 到 Service Locator 模式。

以下from the Angular 2 docs非常相关(强调我的):

We avoid this technique unless we genuinely need it. It encourages a careless grab-bag approach such as we see here. It's difficult to explain, understand, and test. We can't know by inspecting the constructor what this class requires or what it will do. It could acquire services from any ancestor component, not just its own. We're forced to spelunk the implementation to discover what it does.

Framework developers may take this approach when they must acquire services generically and dynamically.

(另外:值得一读 dependency injection in Angular 2 的内容——可选依赖项、工厂提供程序等)

Angular 1 的 docs on the matter引用它与 The Law of Demeter 发生冲突(这当然更像是一个指南而不是法律,对吧?)。

无论如何,需要注意一些额外的事情:

  • 你不会被警告(通过 errors thrown )使用 this 的循环依赖;事实上,这通常是人们用来绕过这些警告的一种技术。

  • 由于除了注入(inject)的内容之外,您现在还依赖于 $injector,因此您的单元测试要么需要模拟 $injector,要么使用类似 module('moduleThatIsUsingInjectorExplicitly', function( $provide) { $provide.value('barcode', barCodeMock);}.

  • 正如上面引述中提到的,您的代码将不太清晰,因为这些“可选”依赖项未在通常的位置定义。

还有很多关于服务定位器模式的其他读物,并将其与 DI 进行了对比。足够有趣,但对我们的实际影响可能有限,特别是因为 JavaScript 缺乏接口(interface)/抽象和 Angular 1 的 DI 实现意味着真正的差异点更少。

关于javascript - 访问一个可能存在也可能不存在的 Angular 服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37683212/

相关文章:

javascript - 将 ArrayBuffer 响应转换为 JSON

javascript - react : parent component props in child without passing explicitly

Javascript isPunct 函数

javascript - 准备好的查询的 Node.js PostgreSQL 单引号问题

javascript - Chart.js - IndexSizeError : Index or size is negative or greater than the allowed amount

javascript - 更新数组中的内部对象时不执行监视

javascript - Angular2 的 NgbModule ng-bootstrap 不起作用

javascript - Uncaught Error : Unknown provider: $rootScopeProvider <- $rootScope

javascript - 如何将标题设置为 <span>/<div> 标签,以便它应该读取数据中的 <br/> 标签并在单独的行中显示工具提示?

javascript - JQuery.submit(function(event){}) 和 JQuery.Ajax