KnockoutJS containerless binding syntax
Kindly wait for a moment: KnockoutJS provides a convenient feature of using a containerless binding syntax for its foreach
binding, as mentioned in Note 4 of the foreach
binding documentation.
The example in the Knockout documentation shows how you can write your bindings like this:
<ul>
<li class="header">Header item</li>
<!-- ko foreach: myItems -->
<li>Item <span data-bind="text: $data"></span></li>
<!-- /ko -->
</ul>
I find it disappointing that AngularJS does not offer a similar syntax.
Angular's ng-repeat-start
and ng-repeat-end
When dealing with ng-repeat
in AngularJS, most examples, like the one jmagnusson shared in their answer, follow this pattern:
<li ng-repeat-start="page in [1,2,3,4,5]"><a href="#">{{page}}</a></li>
<li ng-repeat-end></li>
Initially, I questioned why Angular requires additional markup compared to Knockout, which handles it more elegantly. However, upon reading hitautodestruct's comment on jmagnusson's answer, I started pondering about the purpose of using ng-repeat-start and ng-repeat-end on separate tags.
A cleaner way to use ng-repeat-start
and ng-repeat-end
After examining hitautodestruct's claim, I realized that placing ng-repeat-end
on a separate tag creates unnecessary elements, such as empty <li>
items. While Bootstrap 3 styles these items to appear hidden, they still clutter the generated HTML.
Thankfully, there is a simpler solution to reduce HTML bloat: combine the ng-repeat-end
declaration with the same tag as ng-repeat-start
.
<ul class="pagination">
<li>
<a href="#">«</a>
</li>
<li ng-repeat-start="page in [1,2,3,4,5]" ng-repeat-end><a href="#"></a></li>
<li>
<a href="#">»</a>
</li>
</ul>
This approach offers three benefits:
- Reduced number of HTML tags
- Elimination of useless, empty tags generated by Angular
- Avoidance of generating the
ng-repeat
tag when the array is empty, mirroring Knockout's efficient handling
But there is still a cleaner way
Upon further exploration of comments on this issue in Angular's GitHub repository (https://github.com/angular/angular.js/issues/1891),
it appears that we can achieve the same advantages without using ng-repeat-start
and ng-repeat-end
.
Borrowing from jmagnusson's example once more, a simplified version would look like:
<ul class="pagination">
<li>
<a href="#">«</a>
</li>
<li ng-repeat="page in [1,2,3,4,5,6]"><a href="#">{{page}}</a></li>
<li>
<a href="#">»</a>
</li>
</ul>
So when should you utilize ng-repeat-start
and ng-repeat-end
? According to the angular documentation, it's ideal
...for repeating a series of elements rather than just a single parent element...
Enough talk, let's see some examples!
Fair point; here's a jsbin showcasing five examples of the impact of using or omitting ng-repeat-end
on the same tag.