How do I inherit from parent scope in ngRepeat

16,715 views
Skip to first unread message

mich...@gablit.com

unread,
Jun 25, 2012, 10:12:37 PM6/25/12
to ang...@googlegroups.com
I just want the following to work:

<!doctype html>
<html ng-app>
<head> <script src="http://code.angularjs.org/angular-1.0.1.min.js"></script> </head>
<body>
<span ng-init="count=0">count: {{count}}</span>

<ul>
  <li ng-repeat="n in [1,2,3]"><button ng-click="count = count + n">{{n}}</li>
</ul>
</body>
</html>

Pressing the buttons does not affect count (or at least not the count being displayed), because count is in the root-scope and the buttons are in the ng-repeat scope.  So... how do I fix it in the obvious ways.

Dan Doyon

unread,
Jun 25, 2012, 11:20:18 PM6/25/12
to ang...@googlegroups.com
Should probably look at http://docs.angularjs.org/guide/scope to see how scopes work and there is a description about repeaters. 

what is important to know is that when you use a repeater each element of the model will have its own scope. 

I tweaked your example and just referenced the $parent scope. There are better ways of doing for this, but this works. 
--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To view this discussion on the web visit https://groups.google.com/d/msg/angular/-/JnE5SR41g2sJ.
To post to this group, send email to ang...@googlegroups.com.
To unsubscribe from this group, send email to angular+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/angular?hl=en.

mich...@gablit.com

unread,
Jun 26, 2012, 2:44:53 PM6/26/12
to ang...@googlegroups.com
Ah, $parent was exactly what I was looking for.

But look at this:

<!doctype html>
<html ng-app>
<head> <script src="http://code.angularjs.org/angular-1.0.1.min.js"></script> </head>
<body>
<span ng-init="count=0">count: {{count}}</span>

<ul>
  <li ng-repeat="n in [1,2,3]"><button ng-click="$parent.count = $count + n">{{n}} {{count}}</li>
</ul>
</body>
</html>


This works!  What the hell? Why is $parent necessary in one place but not the other.

Apparently, the evaluator looks through the scope hierarchy when evaluating rvalues, but for lvalues (that are being altered), it only looks in the current scope!  This is sensible, but is it documented somewhere?

The whole point of the doomsday machine is lost if you keep it a secret!  Why didn't you tell the world? 
-- Dr. Strangelove, in Dr. Strangelove

M.

Suller Andras

unread,
Jun 28, 2012, 2:29:17 AM6/28/12
to ang...@googlegroups.com
This is not an angular issue. This is how prototype inheritance works
in Javascript.
Though almost everybody ran into this issue at least once, so it might
be good to put a blinking text in the docs somewhere, with link to
Misko's introduction video:
http://www.youtube.com/watch?v=ljNi8nS5TtQ

Andras
> --
> You received this message because you are subscribed to the Google Groups
> "AngularJS" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/angular/-/Sz8SAVOjYpIJ.

Witold Szczerba

unread,
Jun 28, 2012, 7:47:26 PM6/28/12
to ang...@googlegroups.com
The code below:
http://jsfiddle.net/witoldsz/eTCek/
shows exactly how does inheritance works in JavaScript. It explains the:
count = count + 1; vs $parent.count = count + 1;
case.

Regards,
Witold Szczerba

mich...@gablit.com

unread,
Jun 28, 2012, 8:24:43 PM6/28/12
to ang...@googlegroups.com
On Wednesday, June 27, 2012 11:29:17 PM UTC-7, Andras Suller wrote:
This is not an angular issue. This is how prototype inheritance works
in Javascript.

With all due respect, it is an Angular issue.  The expression language in an Angular template is not Javascript.  The inheritance issue may be analogous to Javascript's inheritance, it may even be caused by Javascript's inheritance, but it's still its own issue.

Witold Szczerba

unread,
Jun 28, 2012, 8:40:00 PM6/28/12
to ang...@googlegroups.com

AngularJS is a JavaScript framework. It is based on JS with all the goodnes and all the constrants of that language.
I may not like it (I am not saying I do), you may not like it, AngularJS team may not like it, but it is what it is.
What would you suggest?

Regards,
Witold Szczerba

--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To view this discussion on the web visit https://groups.google.com/d/msg/angular/-/KYOtDqUDQjwJ.

Suller Andras

unread,
Jun 29, 2012, 3:53:50 AM6/29/12
to ang...@googlegroups.com
Lets assume that when you write "<button ng-click="count = count +
n">" in your template, it is working as you would wanted: it updates
the count variable of the parent scope. Then later as you refactor
your code, you probably want to move this code to a controller
function to keep template clean:

$scope.incCount = function(n) {
$scope.count = $scope.count + n;
}

This will not work as you would expect, because this is pure JavaScript here.
So I think it is better to keep things consistent.

My 2cents,
Andras

mich...@gablit.com

unread,
Jun 29, 2012, 3:31:18 PM6/29/12
to ang...@googlegroups.com
I am not complaining about the behavior of Angular -- in my (largely uninformed) opinion it's the right choice -- I just don't want to hear anyone say, "You should have guessed it worked like that because Javascript works like that."

You know what else works in Javascript?  The ternary operator!  Doesn't work in Angular-language.

A lot of things work differently in Javascript than in Angular language; a lot of things work the same.  The point of having documentation is to describe the way things do in fact work.

The two things missing from the docs so far (the the best of my knowledge):
  • inheritance on scopes works just like Javascript prototypical inheritance
  • each scope has a $parent field.
M.

Suller Andras

unread,
Jun 30, 2012, 1:28:52 AM6/30/12
to ang...@googlegroups.com
On Sat, Jun 30, 2012 at 2:31 AM, <mich...@gablit.com> wrote:
> I am not complaining about the behavior of Angular -- in my (largely
> uninformed) opinion it's the right choice -- I just don't want to hear
> anyone say, "You should have guessed it worked like that because Javascript
> works like that."
>
> You know what else works in Javascript? The ternary operator! Doesn't work
> in Angular-language.

You can use "a && b || c" instead of "a ? b : c" in templates. The ?:
operator will be supported in the future sometime as well.

> A lot of things work differently in Javascript than in Angular language; a
> lot of things work the same. The point of having documentation is to
> describe the way things do in fact work.
>
> The two things missing from the docs so far (the the best of my knowledge):
>
> inheritance on scopes works just like Javascript prototypical inheritance
> each scope has a $parent field.

I think scope inheritance is covered here: http://docs.angularjs.org/guide/scope

Andras

malvo...@gmail.com

unread,
Jun 30, 2012, 10:16:59 PM6/30/12
to ang...@googlegroups.com


On Friday, June 29, 2012 10:28:52 PM UTC-7, Andras Suller wrote:

You can use "a && b || c" instead of "a ? b : c" in templates.
 
I can and do, but remember 1 && 0 || 1 is 1, but 1 ? 0 : 1 is 0.


The ?: operator will be supported in the future sometime as well.

If only I could die now and live then.

M.

Suller Andras

unread,
Jul 1, 2012, 3:25:52 AM7/1/12
to ang...@googlegroups.com
What is your use case? Maybe somebody has a different idea if you
share your initial problem.

Andras

Rana Alkhatib

unread,
Apr 28, 2015, 5:05:38 AM4/28/15
to ang...@googlegroups.com, mich...@gablit.com

 <li ng-repeat="n in [1,2,3]"><button ng-click="$root.count = $root.count + n">{{n}}</li>
Reply all
Reply to author
Forward
0 new messages