Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.
Ben Nadel at CFUNITED 2008 (Washington, D.C.) with: Hal Helms
Ben Nadel at CFUNITED 2008 (Washington, D.C.) with: Hal Helms@halhelms )

ngSwitchWhen Priority Is Higher Than ngRepeat Priority In AngularJS 1.3

By Ben Nadel on

This is a really minor post about a change in directive priority in AngularJS 1.3. The other day, in my post about using multiple templates in a single ngRepeat directive, Boris Litvinsky brought it to my attention that ngSwitchWhen now executes at a higher priority (1,200) than the ngRepeat directive (1,000). While it wasn't necessarily relevant to my previous post, it does mean that as of AngularJS 1.3, the ngSwitchWhen directive can now be used to conditionally link ngRepeat directives.


 
 
 

 
 
 
 
 

Run this demo in my JavaScript Demos project on GitHub.

Prior to AngularJS 1.3, the ngSwitchWhen directive used to execute at priority 800. This means that if you used it on the same element as ngRepeat (priority 1,000), it would transclude the element after ngRepeat had cloned it. It would then attempt to link the second clone in the context of ngSwitch, which is absolutely not what the developer was intending.

As of AngularJS 1.3, the ngSwitchWhen directive executes at priority 1,200 which means that it executes before ngRepeat. As such, the ngSwitchWhen directive can now work in conjunction with the ngSwitch directive to conditionally include an ngRepeat block:

  • <!doctype html>
  • <html ng-app="Demo">
  • <head>
  • <meta charset="utf-8" />
  •  
  • <title>
  • ngSwitchWhen Priority Is Higher Than ngRepeat Priority In AngularJS 1.3
  • </title>
  • </head>
  • <body ng-controller="AppController">
  •  
  • <h1>
  • ngSwitchWhen Priority Is Higher Than ngRepeat Priority In AngularJS 1.3
  • </h1>
  •  
  • <h2>
  • Friends
  • </h2>
  •  
  • <ul ng-switch="!! friends">
  •  
  • <!-- Data is still loading. -->
  • <li ng-switch-when="false">
  •  
  • <em>Loading data...</em>
  •  
  • </li>
  •  
  • <!--
  • Data has loaded and is ready to render.
  • --
  • As of AngularJS 1.3, ngSwitchWhen has a priority of 1,200, which is higher
  • than ngRepeat (which has priority 1,000). As such, the ngSwitchWhen will
  • determine whether or not the LI element is ultimately linked. Then, once it's
  • linked, the ngRepeat directive will determine if it's repeatedly cloned.
  •  
  • PRIOR to AngularJS 1.3, the ngSwitchWhen would have linked AFTER the
  • ngRepeat. However, since it transcludes its content and then gets it linked
  • in the context of the ngSwitch Scope, you end up bypassing the ngRepeat
  • scope for the second transclusion... which is only PART of what makes double-
  • transclusion a difficult use-case (in this case).
  • -->
  • <li
  • ng-switch-when="true"
  • ng-repeat="friend in friends">
  •  
  • {{ friend.name }}
  •  
  • </li>
  • </div>
  •  
  •  
  • <!-- Load scripts. -->
  • <script type="text/javascript" src="../../vendor/angularjs/angular-1.3.8.min.js"></script>
  • <script type="text/javascript">
  •  
  • // Create an application module for our demo.
  • var app = angular.module( "Demo", [] );
  •  
  •  
  • // -------------------------------------------------- //
  • // -------------------------------------------------- //
  •  
  •  
  • // I control the root of the application.
  • app.controller(
  • "AppController",
  • function( $scope, $timeout ) {
  •  
  • $scope.friends = null;
  •  
  •  
  • // Defer the definition of the data so that we can simulate a loading
  • // state while data "comes over the wire."
  • $timeout(
  • function deferLoading() {
  •  
  • $scope.friends = [
  • {
  • id: 1,
  • name: "Sarah"
  • },
  • {
  • id: 2,
  • name: "Tricia"
  • },
  • {
  • id: 3,
  • name: "Kim"
  • }
  • ];
  •  
  • },
  • ( 2 * 1000 )
  • );
  •  
  • }
  • );
  •  
  • </script>
  •  
  • </body>
  • </html>

Personally, I've never run into this limitation (and I'm still on AngularJS 1.0.8 in production). I've never needed to put ngSwitchWhen and ngRepeat on the same element. Typically, I would put ngSwitchWhen on a container and then have the ngRepeat as part of the descendant content. That said, I'm sure there are use-cases where this is a valuable change. And, it's good to see the AngularJS team continually refining and optimizing their directives.




Reader Comments

@André,

Very cool! One thing, though - I believe that ngSwitch is actually at priority:0. It's only the ngSwitchWhen / ngSwitchDefault that is now at priority:1,200.

Reply to this Comment

Post A Comment

You — Get Out Of My Dreams, Get Into My Comments
Live in the Now
Oops!
Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.