如何在不引发错误的情况下检查模块是否存在?

如何在不引发错误的情况下检查模块是否存在?

问题描述:

在 Angular 1.2 中,ngRoute 是一个单独的模块,因此您可以使用其他社区路由器,例如 ui.router.

In Angular 1.2, ngRoute is a separate module so you can use other community routers like ui.router instead.

我正在编写一个开源模块,旨在为多种不同的路由器实现工作.那么如何检查哪个路由器已加载或存在?

I'm writing an open-source module that aims to work for multiple different router implementations. So how can I check which router is loaded or exists?

我在我的模块的工厂内执行以下操作,但它没有按我预期的方式工作:

I'm doing the following inside a factory in my module, but it does not work the way I expect it to:

if (angular.module("ngRoute"))
  // Do ngRoute-specific stuff.
else if (angular.module("ui.router"))
  // Do ui.router-specific stuff.

无论哪个模块未加载,它都会引发错误.例如,如果应用程序使用 ui.router,则 ngRoute 检查会引发以下错误:

It raises an error for whichever module is not loaded. For example, if the app is using ui.router, then the following error is raised for the ngRoute check:

未捕获的错误:[$injector:nomod] 模块ngRoute"不可用!您拼错了模块名称或忘记加载它.如果注册一个模块确保您将依赖项指定为第二个论点.

Uncaught Error: [$injector:nomod] Module 'ngRoute' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.

我不知道一种检查方法不会引发错误;但是,请注意问题在于它是 Uncaught Error,而不是抛出了错误.捕获此类错误的模式如下.

I am not aware of a way of checking without an error being raised; however, notice that the issue is that it was an Uncaught Error, not that an error was thrown. The pattern for catching such an error is the following.

try { angular.module("ngRoute") } catch(err) { /* failed to require */ }

如果发现错误,你可以尝试另一个模块,如果没有,你可以使用第一个.

If an error is caught, you can try the other module, and if not, you can use the first.

如果每个模块的行为都相同,则可以执行以下操作,其中我们定义了一个函数,该函数将尝试列出的模块名称中的第一个,如果抛出错误,则尝试下一个选项.

If your behavior will be the same for each module, you could do something like the following, in which we define a function which will attempt the first of the listed module names, and if an error is thrown, try the next option.

var tryModules = function(names) {
  // accepts a list of module names and
  // attempts to load them, in order.

  // if no options remain, throw an error.
  if( names.length == 0 ) {
    throw new Error("None of the modules could be loaded.");
  }

  // attempt to load the module into m
  var m;
  try {
    m = angular.module(names[0])
  } catch(err) {
    m = null;
  }

  // if it could not be loaded, try the rest of
  // the options. if it was, return it.
  if( m == null ) return tryModules(names.slice(1));
  else return m;
};

tryModules(["ngRoute", "ui.router"]);