Control Manipulation: Projections


In the last chapter, we worked with WinJS Binding Lists, using Binding Templates. Binding Lists also come with the neat feature of projections. Projections provide a different view of your original data source, so you can manipulate the data source by sorting, filtering or grouping a projection without changing the original list.

An example of this would be if one wanted to create a list of hikes in the Greater Seattle area. We need the whole list, but the user might want this information sorted or filtered by difficulty, distance, rating or some other parameter. We can use projections to handle this requirement. Each projection would create a new Binding List to bind to the UI without modifying the original list.

To add a sorting projection, use the createSorted() method:

var sortedListProjection = list.createSorted(sorter);
Where sorter is a function that accepts two arguments to compare.
The sorter function must return:
  1. A negative number if the first argument is less than the second
  2. Zero if the two arguments are equivalent
  3. A positive number if the first argument is greater than the second

When you add or remove any elements from a projection, these changes do propagate back to the source Binding List, and any changes to the source Binding List propagate to all of the projections. However, we recommend that you only edit the original Binding.List, to avoid non-intuitive results. For example, if you add an element to a sorted list, how would you predict its position in the original Binding List?

Try It Out

Check It Out

In the JS:

  1. Add the function to the sortedList and alphabeticalList variables
  2. var sortedList = myList.data.createSorted(descendCompare);
    var alphabeticalList = myList.data.createSorted(alpha);
  3. Add the projection function that will sort the hikes by ratings in descending order.
  4. function descendCompare(first, second) {
        if (first.rating == second.rating)
            return 0;
        else if (first.rating < second.rating)
            return 1;
        else
        return -1;
    }

Check the output, to see if the lists show: the first list sorted alphabetically and the second by rating.

Clicking "Yes" will replace the code in the editor with the correct code.
Are you sure you want to do this?