Advanced Views and Panels

In most applications you’ll encounter dynamic content in some form or another, whether it’s simply allowing content to scroll when displayed on small screens, or having an infinitely scrolling list of content like in Twitter or Apple News.

Prism supports a few key use cases for these to enable you to display dynamic content within your applications. They act a little differently to other views, but we’ll detail these concepts as we go.

Lists

List views display a standard vertically scrolling list of items. They’re declared like so:

<!-- index.xml -->
<list id="myList" item-layout="list-item" />

<!-- list-item.xml -->
<layout>
  <label>$title</label>
</layout>

You’ll notice the item-layout attribute in the above example points to a separate layout file. List views display a vertically scrolling series of rows, where each row has its own pre-defined layout. As this view displays dynamic content, the layout for each individual row is constructed on-demand as items are added to the list.

Lists rely a lot more on JavaScript than other layouts, as they display dynamic content. Let’s see how this works in practice:

const data = [
  { title: 'a' },
  { title: 'b' },
  { title: 'c' }
]

window.myList.delegate = {
  numberOfItems: () => data.length,
  item: (index) => data[index],
  handleItemSelected: (index) => console.log(`Selected item at index: ${index}`),
  handleDeselect: () => console.log(`Deselected item`),
}

As you can see, we’re assigning an object to the delegate property of our list. Delegates allow for a formalised method of communication to occur from Prism to our JavaScript code.

Lists require two functions to be declared in order to display content:

  • numberOfItems: should return the total number of rows present in the list
  • item: should return a flat object containing all of the properties used in displaying a list item

You’ll notice that we say flat object, that’s because Prism supports a limited form of data binding for a List’s row item layouts. Prism can access the top-level properties of an item in order to set a view’s content for you.

In the example above, you can see that in the list item layout we have a single view - a Label. That label’s content is set to $title. This tells Prism that it should look for the actual content of the view from the title property on each object returned from the item(index) => {...} call.

Lists work this way mainly to ensure performance is the best it can possibly be. This is important, especially on mobile, for achieving fluid scrolling without stuttering. This is something that users instinctively expect from native apps.

It’s strongly recommended that you only return the properties for which you intend to display in a list item, rather than a full object with unused properties. This will massively improve performance by reducing the amount of data copied from JavaScript to the native Prism runtime.

It’s also important to note that Prism will automatically toString() any value contained within an item object. It’s a good idea to pre-format objects like dates and numbers to ensure that your data is displayed as intended in a way that’s friendly to end-users. It’s also important for performance reasons for this work to be done outside of any of the delegate functions.

Summing up

In this guide we’ve learnt how to declare the more advanced Panels and Views available in Prism, and how to interact with them in JavaScript to achieve dynamic layouts.

In the next guide, we’ll run through some best practices to make use of when building your layouts.