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

Xåp*_* - 42 angularjs angularjs-routing angularjs-module

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

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

我正在我的模块中的工厂内执行以下操作,但它不能按照我期望的方式工作:

if (angular.module("ngRoute"))
  // Do ngRoute-specific stuff.
else if (angular.module("ui.router"))
  // Do ui.router-specific stuff.
Run Code Online (Sandbox Code Playgroud)

对于未加载的模块,它会引发错误.例如,如果应用程序正在使用ui.router,则会为ngRoute检查引发以下错误:

未捕获错误:[$ injector:nomod]模块'ngRoute'不可用!您要么错误拼写了模块名称,要么忘记加载它.如果注册模块,请确保将依赖项指定为第二个参数.

mat*_*141 57

我不知道一种检查的方法,没有提出错误; 但是,请注意问题是它是一个Uncaught Error,而不是抛出错误.捕获这种错误的模式如下.

try { angular.module("ngRoute") } catch(err) { /* failed to require */ }
Run Code Online (Sandbox Code Playgroud)

如果发现错误,您可以尝试其他模块,如果没有,则可以使用第一个模块.

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

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"]);
Run Code Online (Sandbox Code Playgroud)


小智 9

我会测试服务而不是模块本身.

// In controller
if($injector.has('$route')){

}
if($injector.has('$state')){

}

// In angular config
if($injector.has('$routeProvider')){

}
if($injector.has('$stateProvider')){

}
Run Code Online (Sandbox Code Playgroud)


bwe*_*t87 6

最初的答案是合法的.但是,作为替代方案,当我需要"查找或创建"模块时,我写了这个.有许多用例,但一般来说,它让您不必担心文件加载顺序.你可以把它放在initialModules.js...或者你所有的服务/指令文件的顶部以这样的东西开头.这个小功能对我来说就像一个魅力:

var initialModules = [
  {name: 'app.directives', deps: ['ui.mask']},
  {name: 'app.services'},
  {name: 'app.templates'},
  {name: 'app.controllers'}
];

initialModules.forEach(function(moduleDefinition) {
  findOrCreateModule(moduleDefinition.name, moduleDefinition.deps);
});

function findOrCreateModule(moduleName, deps) {
  deps = deps || [];
  try {
    angular.module(moduleName);
  } catch (error) {
    angular.module(moduleName, deps);
  }
}


///// OR... in like "myDirective.js"
findOrCreateModule('app.directives').directive('myDirective', myDirectiveFunction);
Run Code Online (Sandbox Code Playgroud)