ng-switch and ng-repeat on the same element interfearing
Asked Answered
C

1

12

I encountered behaviour in Angular I did not expect and the purpose of this post is to find out whether this is a bug or intended and possibly an explanation why it is intended.

First see this Plunkr: http://plnkr.co/edit/CB7k9r?p=preview . In the example I created an array called array with three object entries. Further I created a ng-switch based on the content of an input field (called toggle). When the value of toggle is 1 it should print all names of the objects in the array prefixed with "1" and otherwise prefixed with "other".

This does not work as intended an it shows an error:

Error: Argument '?' is required at assertArg 

However the same example rewritten (http://plnkr.co/edit/68Mfux?p=preview ) with an extra div around the list, the ng-switch moved to this div and the ng-switch-when moved from the li to the ul (separating the ng-repeat and the ng-switch-when) does work as intended.

Could someone explain why this is?

Curtin answered 15/3, 2013 at 11:26 Comment(3)
The structure of both Plunkrs seems to be exactly the same, save for the names changing from array to streams. Are you sure you didn't make a mistake?Savdeep
While it is entirely possible I made a mistake, the first Plunker is erroneous while the second is not. I do not understand what is wrong with the first one.Curtin
Ah, thanks for the heads-up. I must have made a mistake forking/saving. It is fixed now plnkr.co/edit/CB7k9r?p=preview does not work plnkr.co/edit/68Mfux?p=preview does. (and I understand now Tiago meant the same thing, sorry)Curtin
S
18

It is "intentional", as it is a product of how angular handles ng-repeat. Essentially, multiple copies of the markup are cloned (the markup inside ng-repeat is used as a template) and are compiled individually for each element you are iterating. As such, angular is basically compiling 3 <li ng-switch-when='1' ....> and 3 <li ng-switch-default ....>, but doing so out of context - there is no ng-switch-on element to compare to.

You can see this happening by inspecting the resulting markup:

<ul ng-switch="" on="toggle">  
  <!-- ngRepeat: entry in array -->
  <!-- ngSwitchWhen: 1 -->
  <!-- ngSwitchWhen: 1 -->
  <!-- ngSwitchWhen: 1 -->
  <!-- ngRepeat: entry in array -->
  <!-- ngSwitchDefault:  -->
  <!-- ngSwitchDefault:  -->
  <!-- ngSwitchDefault:  -->        
</ul>

Both directives - ng-repeat and ng-switch - should be handled with care, as they (unlike, for instance, ng-show or ng-hide) heavily influence structure. The second (working) Plunker is the way to go - only work with directives AFTER (structure-wise, INSIDE) the ng-switch logic.

Sash answered 15/3, 2013 at 13:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.