Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angularjs 如何防止指令绑定到Angular中控制器范围内的元素?_Angularjs_Angularjs Directive - Fatal编程技术网

Angularjs 如何防止指令绑定到Angular中控制器范围内的元素?

Angularjs 如何防止指令绑定到Angular中控制器范围内的元素?,angularjs,angularjs-directive,Angularjs,Angularjs Directive,我有一个Angular应用程序MyApp,它依赖于外部模块(两种不同的地图解决方案),我需要它们,但在不同的控制器中(甚至MyApp中的不同模块) 问题是这两个模块都有绑定到同一个参数的指令(本例中为“中心”),这导致它们都操作单个元素。我想要的是一个指令在一个控制器中是活动的,另一个指令在另一个控制器中是活动的——所以不要让它们同时作用于我的元素 我不想更改外部模块的代码来实现这一点。我发现这是一个非常有趣的问题。下面的答案是不完整的,坦率地说,有点粗糙,但它展示了一种在另一个模块中重命名指令

我有一个Angular应用程序MyApp,它依赖于外部模块(两种不同的地图解决方案),我需要它们,但在不同的控制器中(甚至MyApp中的不同模块)

问题是这两个模块都有绑定到同一个参数的指令(本例中为“中心”),这导致它们都操作单个元素。我想要的是一个指令在一个控制器中是活动的,另一个指令在另一个控制器中是活动的——所以不要让它们同时作用于我的元素


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

我发现这是一个非常有趣的问题。下面的答案是不完整的,坦率地说,有点粗糙,但它展示了一种在另一个模块中重命名指令的方法,而无需修改模块本身的源代码。有很多工作要做,使其接近生产准备,它绝对可以改进

该解决方案需要注意的是,一旦指令被重命名,“旧”名称将不再有效。它还取决于一些角度约定,这些约定可能会随着将来的版本而改变,等等,所以它不是未来的证明。对于复杂的指令,它也可能失败,而且我还没有对它进行任何测试

然而,它证明了这是可以做到的,并且这个概念可能会导致一个功能需求(能够为外部模块命名名称,以防止冲突,比如您正在经历的冲突)

我认为,如果您的用例相当简单,这将解决您的问题,但我不建议在一般情况下使用它

(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');
  });

另一个稍微不那么老套的回答

在包含angular的脚本标记之后立即添加以下内容(在加载任何其他模块之前)


var angularModule=angular.bind(angular,angular.module);
angular.module=函数(moduleName、requires、configFn){
var instance=angularModule(moduleName、requires、configFn);
var指令=instance.directive;
instance.directive=函数(directiveName,directiveFactory){
//您可以根据模块和指令名称在此处重命名指令。我不知道您的特定问题的模块和指令名称。这显然可以推广。
if(instance.name=='module1'&&directiveName=='test'){
directiveName='testa';
}
if(instance.name=='module2'&&directiveName=='test'){
directiveName='testb';
}
返回指令(directiveName、directiveFactory);
}
返回实例;
};

其工作原理是拦截对module.directive的调用,并允许您在创建指令之前重命名该指令

我假设您在指令中没有使用隔离作用域?我不控制指令,它们是我所依赖的模块的一部分。隔离作用域与否真的会有什么区别吗?我只是不希望这两个指令对给定控制器中的元素都有inact。
<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>