Reputation: 195
Im trying to render a menu based on a json object but the links dont get rendered.
function MenuItem(item) {
this.id = item.id;
this.name = item.name;
this.url = item.url;
this.parentid = item.parentid,
this.isSelected = ko.observable(item.isSelected);
this.userRoles = item.userRoles;
if (item.Items) {
this.Items = ko.observableArray($.map(item.Items, function (i) {
return new MenuItem(i);
}));
}
else {
this.Items = ko.observableArray();
}
}
function MenuViewModel(root) {
var self = this;
self.Root = new MenuItem(root);
}
function SampleMenuData() {
return {
id: 0,
name: "Root",
url: null,
parentid: null,
isSelected: false,
userRoles: null,
Items: [
{
id: 1,
name: "Home",
url: "/home/index",
parentid: 0,
isSelected: true,
userRoles: null,
Items: {
},
},
{
id: 4,
name: "Products",
url: "/products/index",
parentid: 0,
isSelected: false,
userRoles: null,
Items: {
},
},
],
};
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<h2>Menu</h2>
<nav data-bind="visible: Root.Items().length > 0">
<ul data-bind="foreach: Root.Items()">
<li>
<a data-bind="attr: { href: url, text: name }">
</a>
</li>
<ul data-bind="foreach: Items()">
<li>
<a data-bind="attr: { href: $data.url, text: $data.name}"> </a>
</li>
</ul>
</ul>
</nav>
<script>
$(function() {
var vm = new MenuViewModel(SampleMenuData());
ko.applyBindings(vm);
});
</script>
If I use something like:
<li data-bind="text: name">
</li>
It will show the value for name correctly, but I actually need to create link based on url property. You can see example here : http://jsfiddle.net/430szwu2/1/
Any ideas why this wouldnt work ?
Thanks.
Upvotes: 2
Views: 40
Reputation: 49123
You're mistakenly setting text
as part of the attr
binding-handler value. Try this instead:
<a data-bind="attr: { href: url }, text: name">
Also:
There's no need for the extra $data
prefix.
Your SampleMenuData
defined the inner Items
property as an object instead of array.
See Documentation and updated Fiddle
Upvotes: 2