0

Given HTML in the form of

<p ng-repeat="item in items" my-directive="item">{{item.Description}}</p>

I would like to dynamically add ng-show from within my-directive. It seems it is not as easy as perhaps it could be. If my-directive was an element instead of an attribute it could simply be done through a template, but alas the same support does not exist for attributes.

My first attempt used the $compile service as described at Add directives from directive in AngularJS. However, that approach relies on the directive being a higher priority than any other, and is therefore applied before the ng-repeat.

My current approach is to manually copy the source for ng-show:

.directive('myDirective', ['$animate', function ($animate) {
    function toBoolean(value) {
        if (typeof value === 'function') {
            value = true;
        } else if (value && value.length !== 0) {
            var v = angular.lowercase("" + value);
            value = !(v == 'f' || v == '0' || v == 'false' || v == 'no' || v == 'n' || v == '[]');
        } else {
            value = false;
        }
        return value;
    }

    return {
        scope: true,
        link: function(scope, elem, attrs) {
            scope.$watch("myWatchExpression",
                function(isActive) {
                    $animate[toBoolean(isActive) ? 'removeClass' : 'addClass'](elem, 'ng-hide');
                }
            );
        }
    };
}])

However, that's obviously not a good long-term solution as it requires updating the custom directive whenever angular changes internally.

Is there any way to perhaps request a directive as an injectable and apply it to the element (without disrupting higher priority directives such as ng-repeat)?

Edit to give context

The directive I'm trying to create is for tabbed items. Ideally the markup looks like:

<tab-container>
    <button ng-repeat="tab in tabs" tab-button="{{tab.id}}">{{tab.name}}</button>
    <div ng-repeat="tab in tabs" tab-view="{{tab.id}}"><ng-include src="{{tab.template}}"/></div>
</tab-container>

Thus I would like ng-click and ng-class directives on a tab-button, and ng-show on a tab-view.

Community
  • 1
  • 1
Alex
  • 7,639
  • 3
  • 45
  • 58
  • 2
    I don't think you need to do what you are doing. Why can't you always just add the `ng-show` directive and control it being true/false using the same logic. Or use a filter on the ng-repeat so that it's not even shown. I couldn't tell exactly when you would want to dynamically add ng-show and what value it would have, but if you tell us how you wanted it to work, then we can suggest an alternative – JoseM Jun 20 '14 at 17:02
  • @JoseM I have edited the question to give context – Alex Jun 22 '14 at 13:05
  • Like Jose said, it sounds more like you should have `ngShow` on each element and control the value if its expression. – gkalpak Jun 22 '14 at 15:18
  • Sure, I could - but I'm creating an abstraction here. I get the feeling that directives in Angular v1 are fundamentally not composable, which is a shame - I hope they get it right in v2 – Alex Jun 23 '14 at 08:49
  • 1
    @AlexG: I don't really understand what you mean by "composable". But wanting to use directives (i.e. something that enhanced HTML's capabilities through a process called compiling) without compiling, is like saying "I want a function to get executed without being called - I hope they fix JS soit can be done" (imo)... – gkalpak Jun 24 '14 at 11:00
  • @ExpertSystem I have edited the question title - what I mean by "without compiling" is "without having to use the `$compile` service myself". And by "composable" I mean directives composed of other directives, as in my case above – Alex Jun 24 '14 at 13:42
  • @AlexG: Mybe a fidddle/plunkr would help... – gkalpak Jun 24 '14 at 21:37

0 Answers0