Yesterday, I looked at how to use a single ngRepeat directive, in AngularJS, to render a list of commingled datasets. In that approach, I used the ngSwitch and ngSwitchWhen directives. While this worked perfectly well, I was concerned that it was causing much of the DOM (Document Object Model) to be compiled twice - once for the ngRepeat and once for each ngSwitchWhen. As such, I wanted to take a stab at creating a "switch" directive that was optimized to work specifically with ngRepeat and commingled data.
My concern with the vanilla ngSwitch / ngSwitchWhen approach is that ngSwitchWhen uses "transclude:element" in its directive configuration. I believe (though I am not 100% sure) that this means that each ngSwitchWhen directive will be re-compiled every time the parent ngRepeat element is cloned and linked. To me, this seems unnecessary for the given context since we already know that the ngRepeat element is going to be compiled.
To get around this, what I'd like is precompile the case/when templates before the ngRepeat directive runs. Then, as each ngRepeat clone is being added to the DOM, we clone and link the appropriate rendering template. The real complexity here is that we need access to two different phases of the directive lifecycle - before ngRepeat and after ngRepeat.
I don't believe that this behavior can be achieved in a single directive. So, what I've done in the following code is to do the precompiling in a pre-ngRepeat directive - bnRepeatSwitch; but, then to have that directive inject a different, post-ngRepeat directive - bnRepeatSwitchOn - which will take care of the per-item linking and template selection.
There's definitely more code here since we have to define new directives; but, if you look at the HTML, there's hardly any difference at all. So, is the added complexity worthwhile? It's hard to say exactly, especially with isolated testing. But, when I look at Chrome Dev Tools, I do see significantly faster rendering times and significantly lower memory usage.
NOTE: I demonstrate the performance and memory benefits of this approach in the video.
This approach isn't quite as flexible as the ngSwitch/ngSwitchWhen approach since my directive clears out the entire ngRepeat content before rendering the selected template. But, that's more a factor of laziness in my implementation rather than a limitation of the approach itself. And, in my experience, these kinds of optimizations do add up and lead to a faster, more responsive user experience as the size of your AngularJS application grows.
Want to use code from this post? Check out the license.