Javascript AngularJS中的可选依赖项

Javascript AngularJS中的可选依赖项,javascript,angularjs,dependency-injection,optional-parameters,Javascript,Angularjs,Dependency Injection,Optional Parameters,我正在尝试用AngularJS实现一个控制器,它可以跨多个页面使用。它利用了一些服务。其中一些会加载到所有页面上,而另一些则不会。我的意思是它是在不同的文件中定义的,这些文件是独立加载的。但如果我没有在所有页面上加载这些服务,我会得到错误: Error: Unknown provider: firstOtionalServiceProvider <- firstOtionalService 不,Angular还不支持开箱即用的可选依赖项。您最好将所有依赖项放在一个模块中,并将其作为一个J

我正在尝试用AngularJS实现一个控制器,它可以跨多个页面使用。它利用了一些服务。其中一些会加载到所有页面上,而另一些则不会。我的意思是它是在不同的文件中定义的,这些文件是独立加载的。但如果我没有在所有页面上加载这些服务,我会得到错误:

Error: Unknown provider: firstOtionalServiceProvider <- firstOtionalService

不,Angular还不支持开箱即用的可选依赖项。您最好将所有依赖项放在一个模块中,并将其作为一个Javascript文件加载。如果您需要另一组依赖项-考虑在另一个JS中创建另一个模块,并将所有公共依赖项放入普通JS。

但是,您描述的行为可以通过以下方式实现。您只需将
$injector
而不是所有依赖项注入控制器,然后手动从中提取依赖项,检查它们是否存在。就是这样:

index.html:

1.js:

2.js:

看它住在哪里!尝试使用
标记并观察控制台输出


另外,正如@Problem所说,您可以从AngularJS 1.1.5开始使用
$injector.has()

显然不使用自动注入。但是,您可以注入喷油器并检查服务:

myApp.controller('MyController', [
    '$scope', '$injector', 'firstRequiredService', 'secondRequiredService', 
    function ($scope, $injector, firstRequiredService, secondRequiredService) {
        if ($injector.has('firstOptionalService')) {
            var firstOptionalService = $injector.get('firstOptionalService');
        }
    }
]);

我可能会同意@Proplematic使用$injector的建议。但是,我可以想到另一个解决方案:在引导文件中使用默认值(
null
)注册所有服务。加载其他文件时,以后的定义将覆盖默认定义,从而在一定程度上创建所需的效果

var app = angular.module('plunker', []);

app.value("service1", null)
   .value("service2", null)
   .factory("service1", function() { return "hello"; });

app.controller('MainCtrl', function($scope, service1, service2) {
  console.log(service1); // hello
  console.log(service2); // null
});

试试这个方法

try {
    angular.module('YourModule').requires.push('Optional dependency module');
} catch(e) {
    console.log(e)
}

“requires”是一组依赖模块。

我就是这样解决的:

var deps = [];

try {
    //Check if optionalModule is available
    angular.module('app').requires.push('optionalModule');
    deps.push('optionalModule');
} catch(e){
    console.log("Warn: module optionalModule not found. Maybe it's normal");
}

angular.module('app', deps).factory('stuff', function($injector) {
    var optionalService;

    if($injector.has('optionalService')) {
        optionalService = $injector.get('optionalService');
    } else {
        console.log('No waffles for you, dear sir');
    }
});

酷!我要他们把$injector.has后传到1.0.7!与@madhead相比,我更喜欢这个答案,因为它使用了
$injector.has
而不是
try
/
catch
@有问题的是,有没有办法使用它将可选变量传递给控制器?我不想创建服务,只想传递一个可选的布尔值或对象变量。这可能吗?@JeremyMoritz如果我理解你的要求,你不能将其用于任意值,但你可以注册一个常量或值提供程序,并以与上面相同的方式使用它。谢谢!正是我需要的。我用的是最新的Angular,所以用has!这有点老套,但很管用。我使用它的地方,我有多个路由共享一个控制器,但只有少数需要一个解决:{}属性注入。这是我的项目与可选参数的最佳答案。这正是我想要的!谢谢我需要使用与模态控制器和ng控制器相同的控制器。对于模态控制器,我需要额外的分解器。
myApp.service('secondService', function(){
    this.action = function(){
        console.log('Second service is loaded');
    }
});
myApp.controller('MyController', [
    '$scope', '$injector', 'firstRequiredService', 'secondRequiredService', 
    function ($scope, $injector, firstRequiredService, secondRequiredService) {
        if ($injector.has('firstOptionalService')) {
            var firstOptionalService = $injector.get('firstOptionalService');
        }
    }
]);
var app = angular.module('plunker', []);

app.value("service1", null)
   .value("service2", null)
   .factory("service1", function() { return "hello"; });

app.controller('MainCtrl', function($scope, service1, service2) {
  console.log(service1); // hello
  console.log(service2); // null
});
try {
    angular.module('YourModule').requires.push('Optional dependency module');
} catch(e) {
    console.log(e)
}
var deps = [];

try {
    //Check if optionalModule is available
    angular.module('app').requires.push('optionalModule');
    deps.push('optionalModule');
} catch(e){
    console.log("Warn: module optionalModule not found. Maybe it's normal");
}

angular.module('app', deps).factory('stuff', function($injector) {
    var optionalService;

    if($injector.has('optionalService')) {
        optionalService = $injector.get('optionalService');
    } else {
        console.log('No waffles for you, dear sir');
    }
});