2014-10-17 93 views
2

我遇到了冲突指令和属性名称的问题。这是我的问题的一个简化版本:有两个指令,其中第一个指令的名称是第二个指令的属性名称:指令名称和属性名称冲突

angular.module('mymodule').directive('property', function() { 
    return { 
     template: '<div>Property Directive</div>' 
    }; 
}); 

angular.module('mymodule').directive('fail', function() { 
    return { 
     scope: { 
      property: '=' 
     }, 
     template: '<div>{{property}}</div>' 
    } 
}); 

当我尝试我的第二个指令添加到一个HTML文件:

<fail property="'test'"></fail> 

我得到以下错误:

Error: [$compile:multidir] Multiple directives [fail, property] asking for template on: <fail property="'test'">http://errors.angularjs.org/1.3.0-rc.4/$compile/multidir?p0=fail&p1=property&p2=template&p3=%3Cfail%20property%3D%22'test'%22%3E 

现在,这不会是一个问题,如果这两个指令是在我的模块,因为他们重新命名很容易。但是我在我的应用程序中使用了来自不同外部模块的指令/属性名称。

我该如何判断角度,property这个属性在这个特殊情况下是不是指令?

+0

也许你可以装饰这些指令2,改变他们的限制,以不同的呢?或者将他们的优先级改为不同,使得终端选项的指令失败优先级更高? – PSL 2014-10-17 01:50:59

+0

http://plnkr.co/edit/5Cfn5T?p=preview根据这些指令的作用,您可以更改限制值。 – PSL 2014-10-17 01:59:48

+0

感谢您的帮助和示例代码。我仍然试图解决这个问题,因为改变其他模块的指令会产生一些副作用。我对Angular很陌生,我觉得我缺少重要的一点。在我看来,像很多人应该遇到这种类型的指令和属性名称冲突的问题... 你知道重命名(或添加前缀)从其他模块的指令名称吗? – forrert 2014-10-21 17:54:09

回答

2

只是扩展我的评论来回答,而不是重新命名的方式,我可以想到的方式是创建一个相同的指令和无效现有的指令。这样你可以有一个适当的命名约定命名为的指令,你正在使用另一个模块。在这里,你需要

  • $compileProvider

    • 要注册一个新的指令,覆盖角度指令构造app.directive
  • $provide service

    • 为了装饰用可怜的名字指令,得到它的定义,并返回只是一个空白无操作的工厂。
    • 您可以用Directive关键字修饰指令后缀。他们也被注册为工厂。

你需要确保这个配置,有针对性的指令登记后显得尤为装饰部。

app.config(['$compileProvider', function ($compileProvider) { 
    //Override directive constructor 
    app.directive = function (name, dirObject) { 
     //Register a directive 
     $compileProvider.directive(name, function() { 
      return dirObject[0]; 
     }); 
    }; 
}]).config(['$provide', function($provide){ 
    //Decorate target directive 
    $provide.decorator('propertyDirective', ['$delegate', function($delegate){ 
     //Just register a new directive with source's definition 
     app.directive('cmProperty', $delegate); 
     //return a no operation factory as directive constructor, to make it inactive 
     return function() { return angular.noop }; 
    }]); 
}]); 

Demo

你可以通过放置在一个恒定的目标指令的名称和运行装饰的循环自动前缀/重命名(与另一名重建),它自动执行此。


更新

看到一个generic solution in my repository

+0

当两个指令具有相同的名称时,这会起作用吗? – 2015-10-14 09:53:49

+1

@przemo_li当你有两个具有相同名称的指令时,工厂是加法的,这意味着当指令被使用时,它将按照优先级的顺序渲染指令编译,你也不能有2个不同的模板等等。当然,这将是特别的目的和故意创造的。例如ng-required指令和其他角度框架中的其他指令。希望这可以帮助! – PSL 2015-10-15 16:47:54

+0

PSL - 如果你仍然在关注这个问题,你可能会看看我在这个问题上的代码实现吗? http://stackoverflow.com/questions/36049473/renaming-3rd-party-angular-directive-using-provide-not-working?noredirect=1#comment59837412_36049473 – jonhobbs 2016-03-19 13:22:45