Using Aurelia I am struggling with binding and repeat.for :
suppose I have in my viewmodel with a property menuItems (an array of MenuItem
) I would like to repeat the menuitems with a custom template :
export class App {
menuItems : MenuItem[];
}
export class MenuItem{
label:string;
}
In my app template I use use a custom element
<require from="./menu-item"></require>
<ul>
<menu-item repeat.for="item of menuItems"></menu-item>
</ul>
My custom template (menu-item.html):
<template>
<li>${label}</li>
</template>
What is the correct way the get the template bound or access the bound MenuItem?
I've tried the following: ${label}
and ${item.label}
but that does not work. I can see in the bind(bindingContext)
callback that bindingContext has a property 'item' : bindingContext.item
which is the MenuItem that is being bound.
I also tried to create bindable attribute on the MenuItem class:
export class MenuItem{
@bindable current any;
label:string;
}
and the following repeater:
<menu-item repeat.for="item of menuItems" current.bind="item"></menu-item>
and a corresponding template
<template>
<li>${current.label}</li>
</template>
note: see edit 1 below, for my comment on this point in the code.
This approach also does not work.
Other explorations included not using a custom element (worked), using <compose view-model='MenuItem', model.bind='item'/>
, does not work in this example either and would be to elaborate, I think.
Working solution, see also Aurelia repeat.for binding on a custom element :
repeat and bind on a custom attribute of the template and viewmodel class:
<menu-item repeat.for="item of menuItems" current.bind="item" containerless></menu-item>
The viewmodel class:
import {bindable, customElement} from 'aurelia-framework'
@customElement('menu-item')
export class MenuItem{
label = "default label";
@bindable current;
constructor(label){
this.label = label;
}
attached(){
console.log("MenuItem = attached");
}
}
I see in the output the html of templates repeated for as many there are MenuItems. But these items are not bound: the <li>
is empty. I expected to see the labels.
in this post I typed "items in menuItems", that's not correct it should be "item of menuItems". But that was not the cause of my struggling, I had it mis-typed in this post only
@jeremy-danyow suggested that
containerless
attribute helps by removing the menu-item element)That plunker works, provided a @bindable
attribute;
Browsers only allow li
elements inside ul
elements. <ul><menu-item></menu-item></ul>
is invalid markup in the same way that <ul><div></div></ul>
is invalid markup.
Consider making a <menu>
element whose template contains the ul
and it's li
elements instead.
One other thing- only a few standard elements are "self closing"- eg inputs, etc. Custom elements must always have a closing tag.
Bad: <menu-item />
Good: <menu-item></menu-item>
You might be wondering "why can't aurelia figure this out for me?"
Valid question. Here's why: Aurelia does not implement a custom html parser. It uses the DOM to parse standard HTML. This is different than other frameworks folks might be accustomed to that implement custom parsers for non-standard markup syntaxes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With