uriDium
uriDium

Reputation: 13440

How do you not override other angular directives when using isolate scope and still being able to call methods in the scope?

I have an anchor tag that I wish to hide or show depending on a value in the model.

<table>
    <tr ng-repeat="item in items">
        <td>Other Stuff</td>
        <td>
            <a href="#/somewhere" ng-show="model.showIt" myCustomDir="some value" onClick="bar(item)" />
        </td>
    </tr>
</table>

Now in my directive I have the following:

app.directive('myCustomDir', function() {
    var def = {
        restrict: 'A',
        scope: {
            onClick: "&"
        },
        link: function(scope, element, attrs) {

            var hover = angular.element("<div><b>Some Text</b></div>");
            var button = hover.find('b');

            button.on('click', function() {
               scope.$apply(function() {
                   scope.onClick();
               })
            });
        }
    };

    return def;
})

The problem is as soon as I include my directive the ng-show one I think no longer works and that is because if I am correct it is because my directive works in isolate scope so the model from the parent scope is no longer present.

How would I get my directive to play nicely with ng-show while still being able to let someone what method they want to call when the tag is clicked.

Plunker for all those interested. http://plnkr.co/edit/BLMCgB

Upvotes: 0

Views: 2734

Answers (2)

zs2020
zs2020

Reputation: 54551

You directive creates an isolated scope. So you need to use $parent to get the value of the current repeater item

ng-show="$parent.item.visible"

If you want to make it more generic, you can take the scope off to make it compatible with other directives. Then you can use scope.$eval to call the function passed in.

myApp.directive('myDirective', function ($document) {
    var definition = {
        restrict: 'A',
        link: function (scope, element, attrs) {
            element.on('click', function () {

                ...

                button.on('click', function () {
                    scope.$apply(function () {
                        scope.$eval(attrs.onClick);
                        hover.remove();
                    })
                });
            });
        }
    }

    return definition;
})

Upvotes: 2

user680786
user680786

Reputation:

If you want allow any global directive - don't declare private scope.
If you want allow only few directives, add links in scope declaration:

scope: {
            onClick: "&",
            ngShow : "&"
        },

To your question in comments:
Declare controller in directive and declare method in this controller. Then in directive template assign ng-click to this method.

var def = {
  restrict: 'A',
  controller: function($scope){
    $scope.callMe = function(){
      console.log('foo');
    }
  }
}

in template:

<div ng-click="callMe()">content</div>

This method will be accessible only inside your directive.

Upvotes: 0

Related Questions