4

I have a directive with the following scope:

scope: {
  copyObject: '&',
  deleteObject: '&'
}

Now, I have a corresponding button in my template which looks like this:

 <button ng-click="copyObject()">Copy</button>

However, I would like to hide the button if there's no function applied to copy-object, for example:

<!-- Should show the copy button -->
<my-directive copy-object="copyObject()"></my-directive>

<!-- Should not show the copy button -->
<my-directive></my-directive>

So I applied the following to my template:

<button ng-click="copyObject()" ng-if="copyObject">Copy</button>

But this does not seem to work, if I check the directives real isolated scope, I notice that, even when the attribute is not entered, the function still exists, so the button is always visible.

Is it possible to detect if a function is bound to the copyObject() or not? And is it a good practice to do so? I'm not sure if the directive should be aware of the bound function or is this some kind of scope access violation?

An example: http://jsfiddle.net/azchpo5q/ (the second button should not be visible because there is no action bound to it).

g00glen00b
  • 41,995
  • 13
  • 95
  • 133
  • The clicking is not the problem (that already works with brackets), but I would like to hide the button if no function is bound to it. I added a fiddle: http://jsfiddle.net/azchpo5q/ The second button should not be visible as it has no `copy-object` attribute. – g00glen00b Oct 29 '14 at 10:53
  • 1
    I found the answer: http://stackoverflow.com/questions/21935099/how-to-check-if-a-method-argument-of-a-directive-is-specified-in-angularjs (I also voted to close as a duplicate) – g00glen00b Oct 29 '14 at 11:03
  • Thx g00glen00b, your answer solved my problem! – SathOkh Nov 08 '16 at 11:25

1 Answers1

3

You can use a function in ng-if to determine if the function is defined.

<button ng-click="copyObject()" ng-if="doShowCopy()">Copy</button>

Then define this method:

 $scope.doShowCopy = function() {
     return (typeof $scope.copyObject == 'function');
 }
Brandon O'Dell
  • 1,171
  • 1
  • 15
  • 22
Prasad K - Google
  • 2,584
  • 1
  • 16
  • 18
  • 5
    The problem is that `typeof $scope.copyObject` is **always** a function, because this is a wrapper function not direct function that comes from outer scope. – dfsq Oct 29 '14 at 10:59
  • Sure? I am guessing it might be defined in the scope, but not as a function!! – Prasad K - Google Oct 29 '14 at 11:01
  • It is defined as a function yes, if I use `directive.isolateScope().copyObject` it returns a function. I solved it thanks to another question though, by using the `attrs` from the `link()` function. I marked it as a duplicate. – g00glen00b Oct 29 '14 at 11:02
  • Absolutely sure. This function which basically tries to evaluate a function in parent scope. – dfsq Oct 29 '14 at 11:02
  • So, is it defined as a function for any type of attribute? I mean how is the angularjs assuming that to be a function? Am just curious!! – Prasad K - Google Oct 29 '14 at 11:05
  • 1
    @Prasad It assumes that because the function is bound as `&`. So AngularJS knows that it should be a function and it returns a wrapper, like @dfsq mentioned. You can see it in this fiddle: http://jsfiddle.net/azchpo5q/2/ – g00glen00b Oct 29 '14 at 11:20
  • Ya, got it! It's defined as a function because it's one-way binding, but not because you are binding a function to it. It's always defined as a function (whether you are binding a function or a string) with a closure inside if it's one way binding! – Prasad K - Google Oct 29 '14 at 12:28