我有一个JSON结构,表示为分层元素。 它看起来如下:
{
"url":"http://docsetups.json",
"partnerId":1,
"fieldDefs":
[
{"roleName":"Make","roleId":1,
"children":[{"roleName":"Invoice Number","roleId":11}]
},
{"roleName":"Model","roleId":2,
"children":[
{"roleName":"Manufacturer","roleId":21},
{"roleName":"EquipmentCode","roleId":22},
{"roleName":"EquipmentSSN","roleId":23}
]
}
]
}
Plunker
我已经在:http://plnkr.co/edit/betBR2xLmcmuQR1dznUK?p=preview
创建了一个plunker我正在使用ng-repeat在元素中将其显示为元素的层次结构,如下所示:
当我点击任一元素时,整个结构会展开,如下所示:
呈现DOM的代码非常简单,如下所示:
<div class="headerItem"
ng-class="{focus: hover}"
ng-mouseenter="hover = true"
ng-mouseleave="hover = false"
data-ng-click="vm.onClick(item.roleName)"
data-ng-repeat="item in vm.documentSetups.fieldDefs">{{item.roleName}}
<div class="subItem" ng-show="vm.isVisible"
data-ng-repeat="subItem in item.children">[ ] {{subItem.roleName}}
</div>
</div>
vm.isVisible
这里要关注的是具有ng-show =&#34; vm.isVisible&#34;的子项目。所以它只显示该值是否为真。
仅显示已点击父级的子项
但是,我只想在点击其父项时显示子项 - 而不是像现在一样显示所有子项。有人可以提供一个很好的方法吗?我希望在没有指令的情况下这样做,因为我感兴趣的是在没有指令的情况下这是否可能,或者在这种情况下代码是否非常错综复杂。
如果您的解决方案包括创建指令,请尽可能简单。感谢。
答案 0 :(得分:1)
我认为您应该为每个项目定义一个标志,以确定该项目是否已打开。 然后将项目本身传递给处理程序:
data-ng-click="vm.onClick(item)
之后 - 你只需要反转isOpen标志:
function onClick(item)
{
item.isOpen = !item.isOpen;
}
整个观看片段:
<div class="headerItem"
ng-class="{focus: hover}"
ng-mouseenter="hover = true"
ng-mouseleave="hover = false"
data-ng-click="vm.onClick(item)" data-ng-repeat="item in vm.documentSetups.fieldDefs">{{item.roleName}}
<div class="subItem" ng-show="item.isOpen" data-ng-repeat="subItem in item.children">[ ] {{subItem.roleName}}</div>
</div>
the plunker:http://plnkr.co/edit/N8mUZaVfmLpnlW4kxzSr?p=preview
答案 1 :(得分:0)
@Oleksii 你的回答非常接近,这确实激励我制定以下答案,所以我感谢你的投入,我做了你的投票。但是,它比你给我的更多。
在Plunker查看解决方案
我分叉了前一个plunker,你可以看到最终的解决方案: http://plnkr.co/edit/QvyHlLh83bEyvlNkskYJ?p=preview
无需指令
现在我可以点击其中一个或两个元素,它们会独立展开。这是示例输出:
我花了一点思考,但我先做的是创建一个新类型,它包含一个roleName(认为它是唯一的)和一个isVisible布尔值。我将该类型称为visibleItem,它看起来像这样:
var visibleItem = function (roleName){
this.isVisible = false;
this.roleName = roleName;
};
之后我创建了一个数组来保存所有visibleItems(每个节点1个):
var visibleItems = [];
现在当我加载json时,我继续为每个节点创建1个visibleItem对象并将其推入visibleItems数组。
$http.get('items.json')
.success(function(data, status, header, config) {
vm.documentSetups=data;
for (var x = 0; x < vm.documentSetups.fieldDefs.length; x++)
{
visibleItems.push(new visibleItem(vm.documentSetups.fieldDefs[x].roleName));
}
})
他们是&#34;键入&#34;通过他们的roleName(认为它是唯一的)。
接下来,我必须编写两个辅助方法(setVisibleItem和getVisibleItem)
function setVisibleItem(roleName)
{
for (var x = 0; x < visibleItems.length;x++)
{
if (visibleItems[x].roleName == roleName)
{
visibleItems[x].isVisible = !visibleItems[x].isVisible;
}
}
}
function getVisibleItem(roleName)
{
for (var x = 0; x < visibleItems.length;x++)
{
if (visibleItems[x].roleName == roleName)
{
return visibleItems[x].isVisible;
}
}
return false;
}
连接帮助方法
最后,我将setVisibleItem连接到元素的ng-click,然后将getVisibleItem连接到ng-show指令。
data-ng-click="vm.onClick(item.roleName)"
data-ng-repeat="item in vm.documentSetups.fieldDefs">{{item.roleName}}
<div class="subItem" ng-show="vm.getVisibleItem(item.roleName)"
data-ng-repeat="subItem in item.children">[ ] {{subItem.roleName}}</div>
</div>
工作原理摘要
基本上每个都只是遍历列表并检查以确保发送的roleName是否与项目的roleName匹配。如果确实如此,则设置或获取值。
在没有指令且没有错误的情况下解决
它比你想象的要多得多,但我没有必要实现一个指令,而且代码仍然相当基础。