确定内部元素应该在AngularJS中显示的最直接方法是什么?

时间:2014-05-09 12:39:31

标签: javascript angularjs

我有一个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在元素中将其显示为元素的层次结构,如下所示:

collapsed hierarchical elements

当我点击任一元素时,整个结构会展开,如下所示:

expanded hierarchical elements

呈现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;的子项目。所以它只显示该值是否为真。

仅显示已点击父级的子项

但是,我只想在点击其父项时显示子项 - 而不是像现在一样显示所有子项。有人可以提供一个很好的方法吗?我希望在没有指令的情况下这样做,因为我感兴趣的是在没有指令的情况下这是否可能,或者在这种情况下代码是否非常错综复杂。

如果您的解决方案包括创建指令,请尽可能简单。感谢。

2 个答案:

答案 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

无需指令

现在我可以点击其中一个或两个元素,它们会独立展开。这是示例输出: solution view

我花了一点思考,但我先做的是创建一个新类型,它包含一个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匹配。如果确实如此,则设置或获取值。

在没有指令且没有错误的情况下解决

它比你想象的要多得多,但我没有必要实现一个指令,而且代码仍然相当基础。