AngularJS ng-repeat 2D array and display only certain values based on index

﹥>﹥吖頭↗ 提交于 2019-12-12 05:09:27

问题


I have the the following two dimensional array:

 SideNavItems= [["Parent Section 1", "Parent Section 2"],["Parent Section 3", "Parent Section 4"]]

I want to use ng-repeat to display them the following way on a page that has tabbed navigation:

Desired output:

When first tab is selected:

Parent Section 1
Parent Section 2

When second tab is selected:

Parent Section 3
Parent Section 4

Current output:

When first tab is selected:

Parent Section 1
Parent Section 2
Parent Section 3
Parent Section 4

I have a $index variable that changes based on what tab is selected. Can I set it so that only the contents of the first array(element 0 of the 2D array) are repeated when the index is 0, the contents of the second array(element 1 of the 2D array) are repeated when the index is 1, and so on if the 2D array had more elements?

Here is the html I have for repeating the arrays:

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

and I don't know if this will be very relevant but here is the HTML for the tabs. The getClass methods giving active classes that change the tabs appearance in CSS. The toggleSelect method changes the current index to the active tab.

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

I have similar arrays with the child sections for each of these parent sections and hope to do the same thing if there is a way to make this work. I guess I would need another variable to act as a second index though...

***EDIT 2/3/15 2:00PM

Using your advice, I was able to get my desired output. I am now trying to get similar functionality for the children of these parent sections and it seems a bit more complicated. I actually have a 3D array:

 [
   [[Parent1Child1, Parent1Child2],[Parent2Child1, Parent2Child2, Parent2Child3]],
   [[Parent3Child1, Parent3Child2],[Parent4Child1, Parent4Child2, Parent4Child3]]
 ]

Desired Output: When first tab is selected:

Parent Section 1
  Parent1Child1
  Parent1Child2

Parent Section 2
  Parent2Child1
  Parent2Child2
  Parent2Child3

When second tab is selected:

Parent Section 3
  Parent3Child1
  Parent3Child2

Parent Section 4
  Parent4Child1
  Parent4Child2
  Parent4Child3

Each section will eventually be an collapsable/expandable accordion and that's what I started coding toward but maybe I need to back up and work on it spitting out the desired input shown above, and then I can play around with ng-click showing/hiding the correct content for the expand/collapse functionality. He is what I have so far and it seems to be close. I describe the output after the code.

toggleSelect code:

 //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>     

With this code, I get the proper children appearing as I click on the corresponding Parent Section header, but the children appear under all the parent sections on the current page. For example:

When first tab is selected and I click on Parent Section 1:

Parent Section 1
  Parent1Child1
  Parent1Child2

Parent Section 2
  Parent1Child1
  Parent1Child2

When first tab is selected and I click on Parent Section 2:

Parent Section 1
  Parent2Child1
  Parent2Child2
  Parent2Child3

Parent Section 2
  Parent2Child1
  Parent2Child2
  Parent2Child3

Am I over complicating things again? How might I work toward getting the proper children with their parents? Thank you so much for your time it is very appreciated.


回答1:


In my opinion, you really want to keep this out of the UI and hide it away in the controller. You already have an action called toggleSelect in your controller by the looks of things, inside that you can set a new scope property to be only the side nav items of the currently selected tab, something like;

$scope.toggleSelect = function(index) {
  // existing code here

  $scope.currentTabSideNavItems = SideNavItems[index];
}

And your markup can be simplified to:

<div id="field">
    <div ng-repeat="item in currentTabSideNavItems">
        <a ng-click="level=2">{{item}}</a>
    </div>
</div>

That way the logic for extracting out the items to be displayed is hidden nicely in your controller, and can be tested.




回答2:


As @DoctorMick said, it's better to "separate logic from view" I made a snippet on jsfiddle with your needs, hope this helps.

<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);
});


来源:https://stackoverflow.com/questions/28302995/angularjs-ng-repeat-2d-array-and-display-only-certain-values-based-on-index

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!