在AngularJS可选依赖 [英] Optional dependencies in AngularJS

查看:189
本文介绍了在AngularJS可选依赖的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在其中跨越多个页面中使用AngularJS实现一个控制器。它利用一些服务。其中一些被装载在所有页面,有些 - 不是。我的意思是它在不同的文件中的定义,并且这些文件被独立地加载。但是,如果我不上的所有页面加载这些服务,我得到错误:

 错误:未知提供商:firstOtionalServiceProvider<  -  firstOtionalService

所以,我需要在所有页面加载脚本。我可以声明依赖性在角可选?例如:

  myApp.controller('myController的',['$范围,firstRequiredService','secondRequiredService','可选:firstOptionalService','可选:secondOptionalService',函数($范围,firstRequiredService,secondRequiredService,firstOptionalService,secondOptionalSerivce){    //不需要检查,因为firstRequiredService不能为空
    firstRequiredService.alwaysDefined();    //如果相关性不解决,我想角设置null作为参数,并检查
    如果(firstOptionalService){
        firstOptionalService.mayBeUndefinedSoCheckNull();
    }}]);


解决方案

没有,角还不支持可选的依赖开箱即用。你最好把你所有的依赖到模块,并加载它为一个JavaScript文件。如果你需要另一套相关性 - 考虑建立在另一个JS另一个模块,并把所有的公共依赖共同JS

不过,你所描述的行为可以用 $注射器服务。您只需注入 $注射器,而不是所有的依赖到控制器,并从中手动拉依赖关系,如果存在检查。就是这样:

index.html的:

 <!DOCTYPE HTML>
< HTML数据-NG-应用=对myApp>
  < HEAD>
    &所述; SCRIPT SRC =htt​​ps://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js>&下; /脚本>
    &所述; SCRIPT SRC =app.js>&下; /脚本>
    &所述; SCRIPT SRC =1.js>&下; /脚本>
    &所述; SCRIPT SRC =2.js>&下; /脚本>
    <标题> 1 LT; /标题>
  < /头>
  <车身数据-NG-控制器=DemoController>
  < /身体GT;
< / HTML>

app.js:

  VAR对myApp = angular.module('对myApp',[]);myApp.service('commonService',函数(){
    this.action =功能(){
        的console.log('公共服务被加载');
    }
});myApp.controller('DemoController',['$范围,$喷油器'功能($范围,$喷油器){
    VAR普遍;
    VAR第一;
    VAR第二;    尝试{
        常见= $ injector.get('commonService');
        的console.log('喷油器有共同的服务!');
    }赶上(E){
        的console.log('喷油器不具有共同的服务!');
    }
    尝试{
        第一= $ injector.get('firstService');
        的console.log('喷油器有服务第一!');
    }赶上(E){
        的console.log('喷油器不具备服务第一!');
    }
    尝试{
        第二= $ injector.get('secondService');
        的console.log('喷油器有第二次的服务!');
    }赶上(E){
        的console.log('注射器还没有第二个服务!');
    }    如果(普通){
        common.action();
    }
    如果(第一){
        first.action();
    }
    如果(第二){
        second.action();
    }
}]);

1.js:

  myApp.service('firstService',函数(){
    this.action =功能(){
        的console.log('第一个服务被加载');
    }
});

2.js:

  myApp.service('secondService',函数(){
    this.action =功能(){
        的console.log(第二业务加载');
    }
});

看到它住在这普拉克!试着玩<脚本方式> 标签,并观察控制台输出

P.S。而且,正如@Problematic说,你可以使用 $ injector.has(),从AngularJS 1.1.5开始。

I'm trying to implement a controller in AngularJS which is used across multiple pages. It makes use of some services. Some of them are loaded on all pages, some - not. I mean it is defined in different files, and these files are loaded independently. But if i do not load these services on all pages i got error:

Error: Unknown provider: firstOtionalServiceProvider <- firstOtionalService

So, i need to load scripts on all pages. Can i declare dependency as optional in Angular? E.g:

myApp.controller('MyController', ['$scope', 'firstRequiredService', 'secondRequiredService', 'optional:firstOptionalService', 'optional:secondOptionalService', function($scope, firstRequiredService, secondRequiredService, firstOptionalService, secondOptionalSerivce){

    // No need to check, as firstRequiredService must not be null
    firstRequiredService.alwaysDefined();

    // If the dependency is not resolved i want Angular to set null as argument and check
    if (firstOptionalService) {
        firstOptionalService.mayBeUndefinedSoCheckNull();
    }

}]);

解决方案

No, Angular does not yet support optional dependencies out of the box. You'd better put all your dependencies into a module and load it as one Javascript file. If you need another set of dependencies - consider creating another module in another JS and putting all common dependencies to common JS.

However, behavior you've described can be achieved with $injector service. You simply inject $injector instead of all your dependencies to a controller and pull dependencies from it manually, checking if they exist. That's it:

index.html:

<!DOCTYPE html>
<html data-ng-app="myApp">
  <head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js"></script>
    <script src="app.js"></script>
    <script src="1.js"></script>
    <script src="2.js"></script>
    <title>1</title>
  </head>
  <body data-ng-controller="DemoController">
  </body>
</html>

app.js:

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

myApp.service('commonService', function(){
    this.action = function(){
        console.log('Common service is loaded');
    }
});

myApp.controller('DemoController', ['$scope', '$injector', function($scope, $injector){
    var common;
    var first;
    var second;

    try{
        common = $injector.get('commonService');
        console.log('Injector has common service!');
    }catch(e){
        console.log('Injector does not have common service!');
    }
    try{
        first = $injector.get('firstService');
        console.log('Injector has first service!');
    }catch(e){
        console.log('Injector does not have first service!');
    }
    try{
        second = $injector.get('secondService');
        console.log('Injector has second service!');
    }catch(e){
        console.log('Injector does not have second service!');
    }

    if(common){
        common.action();
    }
    if(first){
        first.action();
    }
    if(second){
        second.action();
    }
}]);

1.js:

myApp.service('firstService', function(){
    this.action = function(){
        console.log('First service is loaded');
    }
});

2.js:

myApp.service('secondService', function(){
    this.action = function(){
        console.log('Second service is loaded');
    }
});

See it live in this plunk! Try to play with <script> tags and watch for console output.

P.S. And, as @Problematic said, you can use $injector.has(), starting from AngularJS 1.1.5.

这篇关于在AngularJS可选依赖的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆