Passing an attribute value as an argument to an ng-click function in a directive

11,527 views
Skip to first unread message

Dave Merrill

unread,
Jan 6, 2013, 12:04:39 AM1/6/13
to ang...@googlegroups.com
Is it possible for an ng-click within a directive to pass an argument value that was passed in as an attribute? It appears that if I pass the name of the attribute without {{}}, it's passed but not interpolated, so the function gets the name of the attribute, not its value. That's what I'd expect.

What I don't get is that with {{}} around the attribute name in the ng-click function call, nothing appears to happen at all on click. No error, nothing.

No doubt my angular-newb self is missing something obvious, but so far I don't understand.

Dave

Joshua Miller

unread,
Jan 6, 2013, 12:17:09 AM1/6/13
to angular
Hi Dave!

The `ng-click` value is an expression, so everything occurs as javascript and from within the context of the scope in which the element resides. You don't want to pass in a string (interpolated or otherwise) but rather a variable. 

I modified your directive with explanations for each of the cases you listed as well as created the working one. http://jsfiddle.net/joshdmiller/psrhn/7/

Hope this helps!

Josh



Dave

--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To post to this group, send email to ang...@googlegroups.com.
To unsubscribe from this group, send email to angular+u...@googlegroups.com.
Visit this group at http://groups.google.com/group/angular?hl=en-US.
 
 

Venkatraman Dhamodaran

unread,
Jan 6, 2013, 4:03:51 AM1/6/13
to ang...@googlegroups.com
Hi Joshua,

>> From your jsfiddle : "The string is interpolated *before*, when the scope has yet to exist."

When does the interpolation happens in the above case ? Does it happen during the compile phase of ng-click ?

- Venkat


Dave Merrill

unread,
Jan 6, 2013, 1:39:13 PM1/6/13
to ang...@googlegroups.com
Doh! I need to keep better track of what in Angular is a variable name vs a string, and where interpolation happens and doesn't. 

For instance, you can actually pass quoted strings as arguments to ng-click functions (not the ng-click attribute itself), but apparently interpolation doesn't happen in that case.

Dave


On Sunday, January 6, 2013 12:17:09 AM UTC-5, Joshua Miller wrote:
Hi Dave!

The `ng-click` value is an expression, so everything occurs as javascript and from within the context of the scope in which the element resides. You don't want to pass in a string (interpolated or otherwise) but rather a variable. 

I modified your directive with explanations for each of the cases you listed as well as created the working one. http://jsfiddle.net/joshdmiller/psrhn/7/

Hope this helps!

Josh

Joshua Miller

unread,
Jan 6, 2013, 1:44:39 PM1/6/13
to angular
Hey Venkatraman and Dave,

I was incorrect on the interpolated value. Something is not working as expected here as the method is never even called. If you inspect (using Firebug or Chrome Developer Tools) you will see the interpolation on the second link worked correctly (though passing the variable _is_ the correct approach). I cleaned up the fiddle for others to look at: http://jsfiddle.net/joshdmiller/psrhn/9/

Can someone tell us why ng-click is never called on the second button? Is this a bug?

Josh

Dave Merrill

unread,
Jan 6, 2013, 2:13:21 PM1/6/13
to ang...@googlegroups.com
Right, that's what I reported, the method doesn't appear to get called at all. 

I thought you were saying that that was somehow a consequence of interpolation happening too early, before the scope var existed.

Dave

Joshua Miller

unread,
Jan 6, 2013, 2:24:17 PM1/6/13
to angular
Hi Dave!

I did say that, but I misunderstood and was incorrect. It should have worked and I don't know why it didn't, but passing the variable is still the "right" way.

Josh

Dave Merrill

unread,
Jan 6, 2013, 2:35:45 PM1/6/13
to ang...@googlegroups.com
Understood about a variable name being the right way.

d

Peter Bacon Darwin

unread,
Jan 6, 2013, 2:47:53 PM1/6/13
to ang...@googlegroups.com
So the deal is how AngularJS deals with interpolation in attributes.  This is how I understand how it works...  (I might be wrong)

When it comes across an attribute that contains {{}} curly braces it sets up an observer on this attribute, which will interpolate the string at some point in the future, but initially the value of the attribute is set to null.  When the the ng-click directive gets this attribute value, it is null.  This null is what it stores as the expression that will be executed when the anchor is clicked.  Later, in a subsequent digest the interpolation will be done and the attribute will be set to the value you expected but unfortunately this is too late for the ng-click directive, which is not watching the value of the attribute string for changes.

Pete

Joshua Miller

unread,
Jan 6, 2013, 3:07:22 PM1/6/13
to angular
Hi Peter!

Thanks for jumping in. That was my initial thought too. What eventually confused me is that I assumed ng-click would still be called with a null parameter on click. As you can see from the logging statement, the method is never even called. Does ng-click wait for the interpolation to occur, in essence creating a race condition?

Josh

Dave Merrill

unread,
Jan 6, 2013, 5:31:16 PM1/6/13
to ang...@googlegroups.com
Or maybe on some level it looks like this:
  if (typeof ngClickAttributeFunction === 'function')
    ngClickAttributeFunction();

It would have to, if it wanted to avoid crashing if you didn't pass anything.

Dave

Peter Bacon Darwin

unread,
Jan 6, 2013, 5:31:38 PM1/6/13
to ang...@googlegroups.com
What you are actually getting is this:

ng-click="null"

So yes this expression is being evaluated on each click but unsurprisingly it doesn't have any side effects that you can measure.  If you debug into addAttrInterpolateDirective you might see what is happening: https://github.com/angular/angular.js/blob/master/src/ng/compile.js#L1009

Pete

Joshua Miller

unread,
Jan 6, 2013, 5:47:52 PM1/6/13
to angular
This is mostly academic as I don't see any practical use case, but it does render to the DOM with the correct ng-click expression. If I inspect the DOM at that element, it shows the correct function with the interpolated value. When going through the digest loop, shouldn't ng-click it eventually catch up? Or is this a case of always processing the two in the "wrong" order?

As I said, totally academic, but it's always good to get/reinforce an understanding of the internals of angular.

Josh

Peter Bacon Darwin

unread,
Jan 7, 2013, 2:12:52 AM1/7/13
to ang...@googlegroups.com

No ng-click is not watching the expression string itself for changes. It takes a copy of the expression string at compile time and watches the evaluation of that expression.

Pete
...from my mobile.

Reply all
Reply to author
Forward
0 new messages