Your First Loop with Dart Web Components

In which the trusty and powerful loop is given its time to shine in Dart Web UI. Thus far, we've looked at data binding, conditionals, and even custom components with Dart Web UI. But you can't get very far without needing to iterate through a collection and render a template for each element. Not to worry! In this post, I'll show you how to bind a collection to a template in Dart Web UI.

Many loops.
Prerequisites

You may want to read Your First Model Driven View with Dart, which contains more information on getting started and configure the necessary tools. This post assumes you've read my previous posts on Web Components and Dart.

Overview

You can render a <template> tag for each item in a collection. Whenever the collection is modified, the <template> tag is reapplied for every item in the collection (note: we think this will be optimized in future versions of Dart Web UI).

Keeping with the style of Web Components, this iteration is declarative. To bind a collection to a <template>, you can use the iterate attribute. Here is an example:

    <template iterate="fav in userFavorites">  
     <li><span>{{ fav }}</span></li>  
    </template>  

For every item in userFavorites, a new <li> tag will be created.

Example

This example displays a list of language features found in Dart, each with a checkbox. The user can select their favorite language features, which will be printed out in a second, sorted list. This example shows off templates, data binding, event handling, and iteration.

The Dart Code

Here is the Dart code, which sets up the list of language features (the features variable), the collection of favorite features chosen by the user (the userFavorites variable), and the event handler when a user chooses a feature (the addToFavorites function).

 import 'dart:html';  
   
 List<String> features = const <String>['lexical scope',  
                     'closures',  
                     'getters and setters',  
                     'isolates',  
                     'top-level functions',  
                     'optional static types',  
                     'one-line functions',  
                     'familiar syntax',  
                     'map and list literals',  
                     'generics'];  
   
 // TODO try a Set when it can be watched  
 List<String> userFavorites = new List<String>();  
   
 addToFavorites(Event e) {  
  InputElement checkbox = e.target;  
  var fav = checkbox.value;  
    
  if (checkbox.checked) {  
   userFavorites.add(fav);  
  } else if (!checkbox.checked) {  
   var index = userFavorites.indexOf(fav);  
   userFavorites.removeAt(index);  
  }  
    
  userFavorites.sort();  
 }  
   
 main() { }  

The HTML code

Here is the HTML code with the Dart Web Components declarations.

   <ul>  
    <template iterate="feature in features">  
     <li>  
      <label>  
       <input type="checkbox" value="{{ feature }}"  
           on-click="addToFavorites($event)">  
       <span>{{ feature }}</span>  
      </label>  
     </li>  
    </template>  
   </ul>  
     
   <h3>Your favorite features</h3>  
     
   <ul>  
    <template iterate="fav in userFavorites">  
     <li><span>{{ fav }}</span></li>  
    </template>  
   </ul>  

Working demo

Here is an embedded live demo for you to try. It has been compiled to vanilla JavaScript and HTML so that it works in all modern browsers.



(If you can't see the above embedded demo, you can try this direct link.)

Summary

You can declaratively iterate through collections with the <template> tag in Dart Web Components. The collection is bound to the template, which updates any time the collection is updated.

You can see the source for this and more Dart Web Components samples on Github. Meanwhile, read more about Dart Web Components. Have fun!
(Image courtesy of http://www.flickr.com/photos/jenny-pics/3196346379/)

Popular posts from this blog

Lists and arrays in Dart

Converting Array to List in Scala

Null-aware operators in Dart