ux:Class vs. ux:Template

I have some difficulties understanding the difference between a template and a class in Fuse.
Both seem to be mechanisms to create ‘reusable’ nodes. However, what is the exact use case for a template? Couldn’t I just use a class when a template is needed?

In short, you use ux:Template only where they are expected. Specifically, tags like Each, Instance and PageIndicator expect you to specify templates.

ux:Class is generally used whenever you want to create a reusable component.

Templates are instantiated on demand, automatically. Classes must be instantiated / used (by you) explicitly.

Ok. So to follow up on this I have an example where I load in some data containing books and series. I want the books to be displayed on one page and the series to be displayed on another page. Below is my markup.

<App>
    <JavaScript>
        const records = [{
            id: '1',
            name: 'Serie 1',
            type: 'serie'
        },{
            id: '2',
            name: 'Book 1',
            type: 'book'
        },{
            id: '3',
            name: 'Book 2',
            type: 'book'
        },{
            id: '4',
            name: 'Book 3',
            type: 'book'
        },{
            id: '5',
            name: 'Serie 2',
            type: 'serie'
        }]

        const getRecords = type => {
            return records.map(record => {
                return record.type == type
            })
        }

        module.exports = {
            books: getRecords('book'),
            series: getRecords('serie')
        }
    </JavaScript>
    <Page ux:Class="PageList">
        <StackPanel>
            <Each Items="{books}">
                <Text Value="{name}" />
            </Each>
        </StackPanel>
    </Page>
    <DockPanel>
        <PageControl ux:Name="Pages">
            <PageList ux:Name="Books"/>
            <PageList ux:Name="Series"/>
        </PageControl>
    </DockPanel>
</App>

How do I get the books-page to only display the books and the series-page to only display the series? I tried passing in the data with a property but bindings the curly-brace bindings don’t accept dynamic properties I guess. Would this be a good case for a template? And if so, how?

You’re venturing into territory that is not directly related to your original question. To reply in short: ux:Class is what you would use to create your custom component, and it has nothing to do with ux:Template.

Dynamic properties are ok, and that’s explained in Properties.

You will also want to spend some time reading about Observables.

Here’s a way to achieve what you wanted (ES5):

<App>
    <JavaScript>
        var Observable = require("FuseJS/Observable");
        var records = Observable(
            {id: '1', name: 'Serie 1', type: 'serie'},
            {id: '2', name: 'Book 1', type: 'book'},
            {id: '3', name: 'Book 2', type: 'book'},
            {id: '4', name: 'Book 3', type: 'book'},
            {id: '5', name: 'Serie 2', type: 'serie'}
        );

        var books = records.where(function(x) {
            return x.type == "book";
        });

        var series = records.where(function(x) {
            return x.type == "serie";
        });

        module.exports = {
            books: books,
            series: series
        }
    </JavaScript>
    
    <Page ux:Class="PageList">
        <object ux:Property="Items" />
        <StackPanel>
            <Each Items="{ReadProperty Items}">
                <Text Value="{name}" />
            </Each>
        </StackPanel>
    </Page>

    <DockPanel>
        <PageControl ux:Name="Pages">
            <PageList ux:Name="Books" Items="{books}" />
            <PageList ux:Name="Series" Items="{series}" />
        </PageControl>
    </DockPanel>
</App>

Thanks Uldis,

I have been trying to do something with creating properties earlier and passing them into the class. However i couldn’t get it to work, probably because I didn’t create an observable (rookie mistake :)).

Thanks again for clearing this up!

You don’t necessarily need to pass an Observable to an <object type property. Regular arrays should work just fine there too.

However, that ES6 code of yours (getRecords function) certainly didn’t return the actual objects that match your criteria. I think it was just an array of booleans. That might’ve been the problem.

My thinking: since you currently need to use Observables in Fuse apps anyway, why not just go with them and take advantage of the reactive operators (such as the .where that I used) as well?