2015-02-06 85 views
1

我有一个Angular应用程序,MyApp,依赖于外部模块(两种不同的地图解决方案),我需要它们两个,但在不同的控制器(甚至MyApp中的不同模块)。如何防止指令绑定到Angular的控制器范围内的元素?

问题是,两个模块都有指令绑定到相同的参数(在这种情况下'中心'),这导致他们都操纵单个元素。我想要的是一个指令在一个控制器中处于活动状态,另一个指令在另一个控制器中处于活动状态 - 因此不会让他们同时触发我的元素。

我不想改变外部模块的代码来实现这一点。

+0

我假设你没有在你的指令中使用孤立的范围呢? – DonJuwe 2015-02-06 12:21:09

+0

我不是在控制指令,他们是我依赖的模块的一部分。而孤立的范围或没有真正有什么区别?我根本不希望这两个指令都对我的控制器中的元素产生影响。 – 2015-02-09 07:06:54

回答

0

我发现这是一个非常有趣的问题。下面的答案是不完整的,坦率地说,有点冒失,但它演示了一种方法来重命名另一个模块中的指令而不修改模块本身的来源。要做好接近生产的任何准备工作都有很多工作要做,并且绝对可以改进。

解决方法的注意事项是,一旦指令被重命名,“旧”名称将不再起作用。它也取决于一些可能随未来版本而改变的角度约定,因此它不是未来的证明。它也可能会因为复杂的指令而失败,而且我还没有真正做过任何测试。

但是,它表明它可以完成,并且这个概念可能会导致一个特性角度需求(命名空间外部模块以防止发生冲突,如您正在遇到的问题)。

我认为如果你的用例相当简单,这将解决你的问题,但我不会推荐在一般情况下使用它。

(function() { 
      var util = angular.module('util', [], function ($compileProvider) { 
      util.$compileProvider = $compileProvider 
      }) 
      .factory('$directiveRename', function() { 
       var noop = function() { return function() { }; }; 
       return function (module, directive, newDirective) { 
        var injector = angular.injector(['ng', module]); 

        var directive = injector.get(directive + 'Directive'); 
        if(directive) 
        { 

         //there can be multiple directives with the same name but different priority, etc. This is an area where this could definitely be improved. Will only work with simple directives. 
         var renamedDirective = angular.copy(directive[0]); 
         delete renamedDirective['name']; 

         util.$compileProvider.directive(newDirective, function() { 
          return renamedDirective; 
         }); 
        } 

        //noop the old directive 
        //http: //stackoverflow.com/questions/16734506/remove-a-directive-from-module-in-angular 
        angular.module(module).factory(directive + 'Directive', noop); 
       }; 
      }); 
     })(); 

实例:

angular.module('app', ['module1', 'module2', 'util']) 
    .run(function ($directiveRename) { 

     $directiveRename('module1', 'test', 'testa'); 
     $directiveRename('module2', 'test', 'testb'); 
    }); 
0

一种替代,稍少的hackish答案。

添加以下后,包括角脚本标签(任何其他模块被加载之前)

<script type="text/javascript"> 

     var angularModule = angular.bind(angular, angular.module); 

     angular.module = function (moduleName, requires, configFn) { 
      var instance = angularModule(moduleName, requires, configFn); 

      var directive = instance.directive; 

      instance.directive = function (directiveName, directiveFactory) { 

       //You can rename your directive here based on the module and directive name. I don't know the module and directive names for your particular problem. This obviously could be generalized. 
       if (instance.name == 'module1' && directiveName == 'test') { 
        directiveName = 'testa'; 
       } 

       if (instance.name == 'module2' && directiveName == 'test') { 
        directiveName = 'testb'; 
       } 

       return directive(directiveName, directiveFactory); 
      } 

      return instance; 
     }; 
</script> 

这通过拦截来电module.directive并让您有机会之前,将其重命名指令被建造。

相关问题