我有一个类似树状结构的json文件,它可以在几个级别上,看起来像这样,我试图将其转换为菜单(子元素为子菜单):
[
{
"label": {
"en": "Home"
},
"icon": "/images/nav/home.png",
"link": "/",
"type": "basic"
},
{
"label": {
"en": "Channels"
},
"icon": "/images/nav/channels.png",
"type": "children",
"children": [
{
"label": {
"en": "Getting Started"
},
"link": "/getting-started",
"type": "basic"
},
{
"label": {
"en": "Recommendations"
},
"link": "/recommendations",
"type": "basic"
},
{
"label": {
"en": "Calendar View"
},
"link": "/calendar",
"type": "basic"
},
{
"label": {
"en": "My Pictures"
},
"link": "/account/media",
"type": "basic"
},
{
"type": "space"
},
{
"label": {
"en": "All Channels"
},
"link": "/channels",
"type": "basic"
},
{
"label": {
"en": "Channel 1"
},
"link": "/channels/channel-1",
"type": "statuses",
"datasource": "/data/1",
"children": [
{
"label": {
"en": "Channel 1-1"
},
"link": "/channels/channel-1-1",
"type": "basic"
},
{
"label": {
"en": "Channel 1-2"
},
"link": "/channels/channel-1-2",
"type": "basic"
},
{
"label": {
"en": "Channel 1-3"
},
"link": "/channels/channel-1-3",
"type": "basic"
},
{
"label": {
"en": "Channel 1-4"
},
"link": "/channels/channel-1-4",
"type": "basic"
},
{
"label": {
"en": "Channel 1-5"
},
"link": "/channels/channel-1-5",
"type": "basic"
}
]
},
{
"label": {
"en": "Channel 2"
},
"link": "/channels/2",
"type": "statuses",
"datasource": "/data/2",
"children": [
{
"label": {
"en": "Channel 2"
},
"link": "/channels/channel-2",
"type": "basic"
},
{
"label": {
"en": "Channel 2-1"
},
"link": "/channels/channel-2-1",
"type": "basic"
},
{
"label": {
"en": "Channel 2-2"
},
"link": "/channels/channel-2-2",
"type": "basic"
},
{
"label": {
"en": "Channel 2-3"
},
"link": "/channels/channel-2-3",
"type": "basic"
},
{
"label": {
"en": "Channel 2-4"
},
"link": "/channels/channel-2-4",
"type": "basic"
}
]
},
{
"type": "custom",
"content": "<div><span class=\"green_bull\">•</span>Currently Online</div><div><span class=\"red_bull\">•</span>Currently Offline</div>"
}
]
},
{
"label": {
"en": "Shows"
},
"icon": "/images/nav/shows.png",
"type": "children",
"children": [
{
"label": {
"en": "LIVE"
},
"link": "/live",
"type": "basic"
},
{
"label": {
"en": "Browse Shows"
},
"link": "/live",
"type": "basic"
},
{
"label": {
"en": "Full Schedule"
},
"link": "/live",
"type": "basic"
},
{
"label": {
"en": "Upcoming Shows"
},
"type": "components",
"component": "navShow",
"datasource": "/shows/upcoming?limit=3"
}
]
},
{
"label": {
"en": "Community"
},
"icon": "/images/nav/community.png",
"type": "children",
"children": [
{
"label": {
"en": "Latest"
},
"link": "/community",
"type": "basic"
},
{
"label": {
"en": "Best of"
},
"link": "/community/highlight",
"type": "basic"
},
{
"label": {
"en": "Discussion Boards"
},
"link": "http://forum.slooh.askmp.ca/",
"type": "basic"
},
{
"label": {
"en": "Rankings"
},
"link": "/community/rankings",
"type": "basic"
},
{
"label": {
"en": "Full Listings"
},
"link": "/community/listings",
"type": "basic"
},
{
"type": "space"
},
{
"label": {
"en": "Hot this Month"
},
"type": "basic-loaded",
"datasource": "/community/hot"
},
{
"type": "space"
},
{
"type": "component",
"component": "nav",
"datasource": "/data/nav"
},
{
"type": "custom",
"content": "[social media HTML]"
}
]
},
{
"label": {
"en": "About"
},
"icon": "/images/nav/about.png",
"type": "children",
"children": [
{
"label": {
"en": "Our Values"
},
"link": "/about",
"type": "basic"
},
{
"label": {
"en": "In the News"
},
"link": "/about/media",
"type": "basic"
},
{
"label": {
"en": "The Team"
},
"link": "/about/#team",
"type": "basic"
},
{
"label": {
"en": "Guests"
},
"link": "/about/#guests",
"type": "basic"
},
{
"label": {
"en": "Partners"
},
"link": "/about/#partners",
"type": "basic"
},
{
"label": {
"en": "Media Kit"
},
"link": "/about/media",
"type": "basic"
},
{
"label": {
"en": "Contact Us"
},
"link": "/about/#contact",
"type": "basic"
},
{
"label": {
"en": "Upcoming Shows"
},
"type": "components",
"component": "navShow",
"datasource": "/data/shows/upcoming?limit=1"
}
]
},
{
"label": {
"en": "Help"
},
"icon": "/images/nav/help.png",
"link": "/",
"type": "children",
"children": [
{
"label": {
"en": "New here?"
},
"link": "/about",
"type": "basic"
},
{
"type": "space"
},
{
"label": {
"en": "Guides"
},
"link": "/help",
"type": "basic"
},
{
"label": {
"en": "Troubleshooting"
},
"link": "/help/#troubleshooting",
"type": "basic"
},
{
"label": {
"en": "Practice Activities"
},
"link": "/help#practice",
"type": "basic"
},
{
"label": {
"en": "Image Management"
},
"link": "/help/images",
"type": "basic"
},
{
"label": {
"en": "Photography 101"
},
"link": "/help/photography",
"type": "basic"
},
{
"label": {
"en": "What’s What?"
},
"link": "/community/whats",
"type": "basic"
},
{
"label": {
"en": "Hints and Tips"
},
"link": "/help/#hints",
"type": "basic"
},
{
"type": "space"
},
{
"label": {
"en": "Trouble Logging In?"
},
"link": "/help/account",
"type": "basic"
},
{
"label": {
"en": "Pricing Tiers"
},
"link": "/help/#account",
"type": "basic"
},
{
"label": {
"en": "Account FAQs"
},
"link": "/help/#account",
"type": "basic"
},
{
"label": {
"en": "Shows FAQs"
},
"link": "/help/shows",
"type": "basic"
},
{
"label": {
"en": "Reservations FAQs"
},
"link": "/help/faqs",
"type": "basic"
},
{
"type": "space"
},
{
"label": {
"en": "Contact Customer Support"
},
"link": "/help/contact",
"type": "basic"
},
{
"label": {
"en": "Site Feedback"
},
"link": "/help/contact#feedback",
"type": "basic"
}
]
},
{
"label": {
"en": "Settings"
},
"icon": "/images/nav/settings.png",
"link": "/",
"type": "children",
"children": [
{
"label": {
"en": "Personal Profile"
},
"link": "/account",
"type": "basic"
},
{
"label": {
"en": "Subscription Management"
},
"link": "/account/subscription",
"type": "basic"
},
{
"label": {
"en": "Alerts & Email Settings"
},
"link": "/account/#notifications",
"type": "basic"
}
]
}
]
我试图迭代它,并从孩子们那里创建辅助导航。
顶级很容易搞定,第二级几乎就在那里。但是,当映射到子项(在下面的GetChildren中)时,我无法获得任何子数组,只能获得直接对象。所以,我可以获得{child.link},但{child.label.en}会返回错误。我应该更聪明地接近这个吗?
var GetChildren = React.createClass({
render: function() {
var childlink = this.props.data.map(function (child, i){
return (
<a key = {i} href={child.link}> {child.label.en}</a>
);
});
return (
<li className="childlist">
{childlink}
</li>
);
}
});
var MenuComponent = React.createClass({
getInitialState: function() {
return {
condition: [],
menuItem: []
};
},
componentDidMount: function() {
$.get(this.props.source, function(result) {
var items = result;
if (this.isMounted()) {
this.setState({
menuItem: items,
condition: false
});
}
}.bind(this));
},
render: function(condition) {
PrimaryMenu = this.state.menuItem || [];
return (
<aside>
<nav>
<ul>
{PrimaryMenu.map(function(el, i){
if (el.type == "basic") {
var PrimaryMenuLink = el.link;
} else {
PrimaryMenuLink = '/' +el.label.en.toLowerCase();
}
return <li key={i}> <a data-nav={'nav-' + el.label.en.toLowerCase()}>
{el.label.en}</a></li>
})}
</ul>
</nav>
{PrimaryMenu.map(function(el, i){
if (el.type == "children") {
return <section key={i} id={'nav-' + el.label.en.toLowerCase()}><ul><GetChildren data={el.children}/> </ul></section>
}
})}
</aside>
);
}
});
答案 0 :(得分:1)
问题可能来自某些没有label
属性的json节点。喜欢这个节点:
{
"type": "space"
},
因此,在阅读label
时,它会在en
属性上生成“无法读取未定义的属性”。
您应该验证所有children
个节点以确保label
存在。验证link
也是为了避免将undefined
作为href
道具