AngularJS ng-repeat 二维数组并根据索引仅显示某些值
AngularJS ng-repeat 2D array and display only certain values based on index
我有以下二维数组:
SideNavItems= [["Parent Section 1", "Parent Section 2"],["Parent Section 3", "Parent Section 4"]]
我想使用 ng-repeat 在具有标签式导航的页面上以下列方式显示它们:
期望的输出:
选择第一个选项卡时:
Parent Section 1
Parent Section 2
选择第二个选项卡时:
Parent Section 3
Parent Section 4
当前输出:
选择第一个选项卡时:
Parent Section 1
Parent Section 2
Parent Section 3
Parent Section 4
我有一个 $index 变量,它根据选择的选项卡而变化。我可以设置它以便当索引为 0 时仅重复第一个数组的内容(二维数组的元素 0),当索引为 1 时重复第二个数组的内容(二维数组的元素 1) , 如果二维数组有更多元素,依此类推?
这是我用来重复数组的 html:
<div id="field">
<div ng-repeat="row in SideNavItems">
<div ng-repeat="cell in row" >
<a ng-click="level=2">{{cell}}</a>
</div>
</div>
</div>
我不知道这是否非常相关,但这是选项卡的 HTML。 getClass 方法激活 类,改变 CSS 中的选项卡外观。 toggleSelect 方法将当前索引更改为活动选项卡。
<nav>
<ul>
<li ng-class="getClass($index)" ng-repeat="tab in tabs">
<a ng-click="toggleSelect($index)" ng-class="getLinkClass($index)">{{tab}}</a>
</li>
</ul>
</nav>
对于这些 parent 部分中的每一个部分,我都有类似的数组 child 部分,如果有办法使这项工作,我希望做同样的事情。我想我需要另一个变量来充当第二个索引...
***编辑 2/3/15 2:00PM
根据你的建议,我得到了我想要的输出。我现在正在尝试为这些 parent 部分的 children 获得类似的功能,但它似乎有点复杂。我实际上有一个 3D 数组:
[
[[Parent1Child1, Parent1Child2],[Parent2Child1, Parent2Child2, Parent2Child3]],
[[Parent3Child1, Parent3Child2],[Parent4Child1, Parent4Child2, Parent4Child3]]
]
期望的输出:
选择第一个选项卡时:
Parent Section 1
Parent1Child1
Parent1Child2
Parent Section 2
Parent2Child1
Parent2Child2
Parent2Child3
选择第二个选项卡时:
Parent Section 3
Parent3Child1
Parent3Child2
Parent Section 4
Parent4Child1
Parent4Child2
Parent4Child3
每个部分最终都会是一个 collapsable/expandable 手风琴,这就是我开始编码的方向,但也许我需要备份并处理它吐出上面显示的所需输入,然后我可以玩ng-click showing/hiding expand/collapse 功能的正确内容。他是我到目前为止所拥有的,而且似乎很接近。我在代码后描述输出。
切换选择代码:
//gets tab tiles order from csv
$scope.tabs= tabsService.mainTabs;
//Assigns active classes to main tabbed navigation
$scope.selectedIndex = 0;
$scope.sideNavItems = productCategoryService.sideNavItems;
$scope.sideNavChildren = productCategoryService.sideNavChildren;
$scope.toggleSelect = function(ind){
$scope.selectedIndex = ind;
$scope.currentTabSideNavItems = $scope.sideNavItems[ind];
$scope.selectedChildIndex = 0;
$scope.toggleChildIndex = function(childIndex){
$scope.selectedChildIndex = childIndex;
$scope.currentSideNavChildren = $scope.sideNavChildren[ind][childIndex];
}
}
HTML
<div id="field">
<div ng-repeat="item in currentTabSideNavItems">
<a ng-click="toggleChildIndex($index)">{{item}}</a>
<div ng-repeat="child in currentSideNavChildren">
<a ng-click="toggleChildIndex($index)">{{child}}</a>
</div>
</div>
</div>
使用此代码,当我单击相应的 Parent 部分 header 时,我得到了正确的 children,但是 children 出现在所有当前页面上的 parent 个部分。例如:
选择第一个选项卡并单击 Parent 第 1 部分:
Parent Section 1
Parent1Child1
Parent1Child2
Parent Section 2
Parent1Child1
Parent1Child2
选择第一个选项卡并单击 Parent 第 2 部分:
Parent Section 1
Parent2Child1
Parent2Child2
Parent2Child3
Parent Section 2
Parent2Child1
Parent2Child2
Parent2Child3
我是不是又把事情复杂化了?我怎样才能让他们的 parent 得到合适的 children?非常感谢您的宝贵时间。
在我看来,您确实希望将其排除在 UI 之外并将其隐藏在控制器中。从外观上看,您的控制器中已经有一个名为 toggleSelect 的操作,在其中您可以将新范围 属性 设置为仅当前所选选项卡的侧导航项,例如;
$scope.toggleSelect = function(index) {
// existing code here
$scope.currentTabSideNavItems = SideNavItems[index];
}
您的标记可以简化为:
<div id="field">
<div ng-repeat="item in currentTabSideNavItems">
<a ng-click="level=2">{{item}}</a>
</div>
</div>
这样,提取要显示的项目的逻辑就很好地隐藏在您的控制器中,并且可以进行测试。
正如@DoctorMick 所说,最好 "separate logic from view" 我做了一个 snippet on jsfiddle with your needs,希望这对您有所帮助。
<section ng-app="App" ng-controller="Ctrl">
<nav>
<ul>
<li ng-repeat="tab in tabs" ng-click="updateSideNavItems($index)" ng-class="{active: $index === currentIndex}"> <a>{{tab}}</a>
</li>
</ul>
</nav>
<div id="field">
<div ng-repeat="cell in SideNavItems">
{{cell}}
</div>
</div>
</section>
var app = angular.module('App', []);
app.controller('Ctrl', function ($scope) {
var SideNavItems = [
["Parent Section 1", "Parent Section 2"],
["Parent Section 3", "Parent Section 4"]
];
$scope.tabs = ['tab1', 'tab2', 'tab3'];
$scope.updateSideNavItems = function updateSideNavItems(index) {
$scope.currentIndex = index;
if (index === 0) $scope.SideNavItems = SideNavItems[0];
else if (index === 1) $scope.SideNavItems = SideNavItems[1];
else $scope.SideNavItems = [].concat.apply([], SideNavItems);
}
// defaults
$scope.currentIndex = 0;
$scope.updateSideNavItems($scope.currentIndex);
});
我有以下二维数组:
SideNavItems= [["Parent Section 1", "Parent Section 2"],["Parent Section 3", "Parent Section 4"]]
我想使用 ng-repeat 在具有标签式导航的页面上以下列方式显示它们:
期望的输出:
选择第一个选项卡时:
Parent Section 1
Parent Section 2
选择第二个选项卡时:
Parent Section 3
Parent Section 4
当前输出:
选择第一个选项卡时:
Parent Section 1
Parent Section 2
Parent Section 3
Parent Section 4
我有一个 $index 变量,它根据选择的选项卡而变化。我可以设置它以便当索引为 0 时仅重复第一个数组的内容(二维数组的元素 0),当索引为 1 时重复第二个数组的内容(二维数组的元素 1) , 如果二维数组有更多元素,依此类推?
这是我用来重复数组的 html:
<div id="field">
<div ng-repeat="row in SideNavItems">
<div ng-repeat="cell in row" >
<a ng-click="level=2">{{cell}}</a>
</div>
</div>
</div>
我不知道这是否非常相关,但这是选项卡的 HTML。 getClass 方法激活 类,改变 CSS 中的选项卡外观。 toggleSelect 方法将当前索引更改为活动选项卡。
<nav>
<ul>
<li ng-class="getClass($index)" ng-repeat="tab in tabs">
<a ng-click="toggleSelect($index)" ng-class="getLinkClass($index)">{{tab}}</a>
</li>
</ul>
</nav>
对于这些 parent 部分中的每一个部分,我都有类似的数组 child 部分,如果有办法使这项工作,我希望做同样的事情。我想我需要另一个变量来充当第二个索引...
***编辑 2/3/15 2:00PM
根据你的建议,我得到了我想要的输出。我现在正在尝试为这些 parent 部分的 children 获得类似的功能,但它似乎有点复杂。我实际上有一个 3D 数组:
[
[[Parent1Child1, Parent1Child2],[Parent2Child1, Parent2Child2, Parent2Child3]],
[[Parent3Child1, Parent3Child2],[Parent4Child1, Parent4Child2, Parent4Child3]]
]
期望的输出: 选择第一个选项卡时:
Parent Section 1
Parent1Child1
Parent1Child2
Parent Section 2
Parent2Child1
Parent2Child2
Parent2Child3
选择第二个选项卡时:
Parent Section 3
Parent3Child1
Parent3Child2
Parent Section 4
Parent4Child1
Parent4Child2
Parent4Child3
每个部分最终都会是一个 collapsable/expandable 手风琴,这就是我开始编码的方向,但也许我需要备份并处理它吐出上面显示的所需输入,然后我可以玩ng-click showing/hiding expand/collapse 功能的正确内容。他是我到目前为止所拥有的,而且似乎很接近。我在代码后描述输出。
切换选择代码:
//gets tab tiles order from csv
$scope.tabs= tabsService.mainTabs;
//Assigns active classes to main tabbed navigation
$scope.selectedIndex = 0;
$scope.sideNavItems = productCategoryService.sideNavItems;
$scope.sideNavChildren = productCategoryService.sideNavChildren;
$scope.toggleSelect = function(ind){
$scope.selectedIndex = ind;
$scope.currentTabSideNavItems = $scope.sideNavItems[ind];
$scope.selectedChildIndex = 0;
$scope.toggleChildIndex = function(childIndex){
$scope.selectedChildIndex = childIndex;
$scope.currentSideNavChildren = $scope.sideNavChildren[ind][childIndex];
}
}
HTML
<div id="field">
<div ng-repeat="item in currentTabSideNavItems">
<a ng-click="toggleChildIndex($index)">{{item}}</a>
<div ng-repeat="child in currentSideNavChildren">
<a ng-click="toggleChildIndex($index)">{{child}}</a>
</div>
</div>
</div>
使用此代码,当我单击相应的 Parent 部分 header 时,我得到了正确的 children,但是 children 出现在所有当前页面上的 parent 个部分。例如:
选择第一个选项卡并单击 Parent 第 1 部分:
Parent Section 1
Parent1Child1
Parent1Child2
Parent Section 2
Parent1Child1
Parent1Child2
选择第一个选项卡并单击 Parent 第 2 部分:
Parent Section 1
Parent2Child1
Parent2Child2
Parent2Child3
Parent Section 2
Parent2Child1
Parent2Child2
Parent2Child3
我是不是又把事情复杂化了?我怎样才能让他们的 parent 得到合适的 children?非常感谢您的宝贵时间。
在我看来,您确实希望将其排除在 UI 之外并将其隐藏在控制器中。从外观上看,您的控制器中已经有一个名为 toggleSelect 的操作,在其中您可以将新范围 属性 设置为仅当前所选选项卡的侧导航项,例如;
$scope.toggleSelect = function(index) {
// existing code here
$scope.currentTabSideNavItems = SideNavItems[index];
}
您的标记可以简化为:
<div id="field">
<div ng-repeat="item in currentTabSideNavItems">
<a ng-click="level=2">{{item}}</a>
</div>
</div>
这样,提取要显示的项目的逻辑就很好地隐藏在您的控制器中,并且可以进行测试。
正如@DoctorMick 所说,最好 "separate logic from view" 我做了一个 snippet on jsfiddle with your needs,希望这对您有所帮助。
<section ng-app="App" ng-controller="Ctrl">
<nav>
<ul>
<li ng-repeat="tab in tabs" ng-click="updateSideNavItems($index)" ng-class="{active: $index === currentIndex}"> <a>{{tab}}</a>
</li>
</ul>
</nav>
<div id="field">
<div ng-repeat="cell in SideNavItems">
{{cell}}
</div>
</div>
</section>
var app = angular.module('App', []);
app.controller('Ctrl', function ($scope) {
var SideNavItems = [
["Parent Section 1", "Parent Section 2"],
["Parent Section 3", "Parent Section 4"]
];
$scope.tabs = ['tab1', 'tab2', 'tab3'];
$scope.updateSideNavItems = function updateSideNavItems(index) {
$scope.currentIndex = index;
if (index === 0) $scope.SideNavItems = SideNavItems[0];
else if (index === 1) $scope.SideNavItems = SideNavItems[1];
else $scope.SideNavItems = [].concat.apply([], SideNavItems);
}
// defaults
$scope.currentIndex = 0;
$scope.updateSideNavItems($scope.currentIndex);
});