Components provide a way to extract large template fragments into reusable modules and attach all the neccessary methods to them (methods of the closest component are looked first when a user function is found in a condition or event handler). Now component is a plain object with template
and funcs
properties, which is added to the as.components
object by key:
as.components['items-list'] = {
template: '- {$value['title']}
',
funcs: { handleClick: function(event) { console.log('Click!') } }
}
Then you can use the component in any template as a custom element:
<div asmodel="data.tasks">
/* ... */
<items-list></items-list>
/* ... */
</div>
You can reference the component itself inside its template if your application logic requires that. Be careful though not to end up in infinite recursion doing this.
For example, an ideal option will be calling the component inside a collection rendering template: in real data you won't get infinite depth nesting, and eventually the recursion will stop on an empty list.
In order for the recursion to work you will have to use relative object paths. Take a look at the following example:
as.components['items-list'] = {
template: '<ul asmodel=".items">\
<li">{$value[\'title\']}</li>\
</ul>'
}
var data = { items:
[
{ title: 'Food', items:
[
{ title: 'Apples', items: [] },
{ title: 'Cookies', items: [] },
{ title: 'Fish', items:
[
{ title: 'Salmon', items: [] },
{ title: 'Herring', items: [] }
]
},
{ title: 'Water', items: [] }
]
},
{ title: 'Other', items:
[
{ title: 'Wash powder', items: [] },
{ title: 'Paper towels', items: [] }
]
}
]
}
<h1>Shopping list</h1>
<ul asmodel="data.items">
<li>
<div>{$value['title']}</div>
<items-list></items-list>
</li>
</ul>
Notice how by rewriting the model and the template slightly you can make the list header the root element of the structure:
var data = { items:
[
{ title: 'Shopping list', items:
[
{ title: 'Food', items: [ /* ... */ ] },
{ title: 'Other', items: [ /* ... */ ] }
]
}
]
}
<ul asmodel="data.items">
<li>
<div>{$value['title']}</div>
<items-list></items-list>
</li>
</ul>
If you only need recursion and don't need methods, you can implement the above example without creating a component. Autosync supports the special asref
attribute for that:
<div asmodel="data">
<h1>Shopping list</h1>
<ul asmodel=".items" asref="items-list">
<li>
<div>{$value['title']}</div>
<items-list></items-list>
</li>
</ul>
</div>
When Autosync encounters this attribute, it will automatically create a component with a template equal to outerHTML
of the given element.
If the data comes from the server with the "redundant" root element, but you don't want to do data transformation on receive, you can set asmodel
to data.items.0
in the outmost template, because integer number indexes are totally correct keys for Autosync.