3

I am using a third party lib with the following custom attribute directive:

angular.directive('snapDrawer', function () {
'use strict';
return {
  restrict: 'AE',
    ...

So if the attribute "snap-drawer" is found in an HTML element the directive implementation has a match and fires, for example:

<div snap-drawer></div>

I am using Angular 1.3 which has an "AllOrNothing" approach to ng-attr where if the value conditional is undefined then the attribute does not render like so:

<div ng-attr-snap-drawer="{{data.addSnapDrawer}}"></div>

100% fact this works, the value of data.addSnapDrawer in my controller is undefined and the snap-drawer attr does not render in the DOM

I have verified that Angular 1.3 does this AllOrNothing approach with ng-attr here: What is the best way to conditionally apply attributes in Angular? (take a look at Mathew Foscarini's answer)

BUT what does render in the DOM is:

<div ng-attr-snap-drawer="{{data.addSnapDrawer}}" class="snap-drawer snap-drawer-left" style=""></div>

So, unbelievably, the angular.directive('snapDrawer') is matching to "ng-attr-snap-drawer". How can this be, I am really shocked that AngularJS, in all its glory, has a bug like this.

I cannot find anything online. I cannot set snap-drawer="false" I need it to not appear in the DOM, which I achieved by upgrading from Angular 1.2 to 1.3.

Community
  • 1
  • 1
Brian Ogden
  • 18,439
  • 10
  • 97
  • 176
  • A general rule while creating new custom attribute is to not name it with prefix ng as the later versions of angularjs may come with same name. – sms Mar 31 '15 at 07:21
  • That is what is so perplexing about this issue, my custom attribute is named 'snapDrawer', no ng prefix, see my angular.directive in my question. Angular is matching the "snap-drawer" part of "ng-attr-snap-drawer" and "ng-attr-snap-drawer" is being used conditionally to render "snap-drawer" attribute or not – Brian Ogden Mar 31 '15 at 07:55
  • can you prefix snap-drawer with some other custom words like Brian-snap-drawer. – sms Mar 31 '15 at 09:09
  • No, snap-drawer is part of a third party lib so I want to avoid changes that would break if I update that lib. snap-drawer has to be the custom attribute name, thanks though – Brian Ogden Mar 31 '15 at 15:21
  • *"So, unbelievably, the angular.directive('snapDrawer') is matching to "ng-attr-snap-drawer". How can this be, I am really shocked that AngularJS, in all its glory, has a bug like this."* Is that not exactly what the [documentation says it should do](https://docs.angularjs.org/guide/directive#-ngattr-attribute-bindings)? (though i'm having problems finding version-relevant documentation of the same) – Kevin B Mar 31 '15 at 15:42
  • https://code.angularjs.org/1.3.15/docs/guide/directive#-ngattr-attribute-bindings – Kevin B Mar 31 '15 at 15:47
  • Can you just use an ng-if that omits the entire div if the value is undefined? should serve the same purpose. – Kevin B Mar 31 '15 at 16:22
  • My issue with that is that the div that would be omitted is a wrapper for alot of child elements that I don't want repeated, so
    lots of child elements
    . I do not want all the child content repeated but I could make a template of the child content I guess
    – Brian Ogden Mar 31 '15 at 16:25
  • The one part of this whole question that i'm still confused about is why you consider this to be a bug. `ng-attr-snap-drawer` should and will cause any directives named `snapDrawer` to be called. The purpose of that is so that you can use the directive in areas where custom attributes would be invalid, such as within an svg. – Kevin B Mar 31 '15 at 16:37
  • I see it as a bug because AngularJs is processing a custom attribute directive on "ng-attr-my-custom-attribute", that is not a match, ng-attr is a built in AngularJs directive, it is not the attribute "my-custom-attribute" – Brian Ogden Mar 31 '15 at 18:16

1 Answers1

1

This is old, but I stumbled upon something very similar. https://github.com/angular/angular.js/issues/16441 - angular authors made it this way.

You need to devise a different way (depending on your usecase) to conditionally apply directives (e.g. use ng-switch and have two versions of the HTML; one with the directive and one without, or have a terminal directive with high priority that evaluates the expression during the linking phase, applies the necessary directive(s) and compiles the element).

ornic
  • 332
  • 3
  • 9