2015-02-06 84 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並讓您有機會之前,將其重命名指令被建造。

相關問題