Skip to content
Permalink
Branch: master
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
73 lines (55 sloc) 3.42 KB

Conditionals and Lists

While HTML itself does not support conditionally displaying elements or repeating elements, it is a critical part of building any web application. In Marko, this functionality is provided by the <if> and <for> tags.

Conditionals

The <if> tag recieves an argument which is used to determine if its body content should be present.

<if(user.loggedOut)>
    <a href="/login">Log in</a>
</if>

As you might expect, there are also <else> and <else-if> tags as well:

<if(user.loggedOut)>
    <a href="/login">Log in</a>
</if>
<else-if(!user.trappedForever)>
    <a href="/logout">Log out</a>
</else-if>
<else>
    Hey ${user.name}!
</else>

Lists

If you have a list of data and need to represent it in the UI, the <for> tag is probably what you're looking for. The <for> tag passes each item and its index to its body as parameters.

<ul>
    <for|color, index| of=colors>
        <li>${index}: ${color}</li>
    </for>
</ul>

The <for> tag actually support 3 different flavors:

Always set a key

Marko automatically keeps your UI in sync with the state behind it, but one place where it needs a little extra help is repeated content. Specifying keys gives Marko a way to identify items in a list and keep track of which items have been changed, added, or removed.

A key should be a string or number that uniquely identifies an item in the list and differentiates it from its siblings. The same key value should never be used twice! Often, you will use something like an id property.

<for|user| of=users>
    <user-card key=user.id data=user/>
</for>

ProTip: If you have multiple tags underneath <for>, you can key only the first tag and that is enough to properly identify its sibilings as well

<dl>
    <for|entry| of=entries>
        <!-- only the first tag needs a key -->
        <dt key=entry.id>${entry.word}</dt>
        <!-- This key can be omitted -->
        <dd>${entry.definition}</dd>
    </for>
</dl>

Note: If a key is not set, Marko will use the index of an item as its key. However this only works perfectly if items are only ever added or removed at the end of a list. Here's an example where things break down: if we have a list of ["A", "B", "C"] and reverse the order, index keys would cause "A" to be transformed into "C" (and "C" into "A"), rather than just swapping them. Additionally if these components contained state, the new "C" would contain the state from the old "A" (and vice-versa). Be aware, stateful components include tags like the native <input> element. For this reason it is always recommended to set a key on tags in a <for>.

You can’t perform that action at this time.