使用ng-repeat

时间:2017-02-09 23:29:23

标签: angularjs json

我知道问题标题有点模糊,但我不知道还有什么可以称之为。基本上,这是我的问题:

我有一个带子菜单的角度菜单。我将每个菜单项分开,子菜单项注入ng-repeat。这很好,但问题是我想在一个ng-repeat中运行整个菜单,并且json文件不仅包含子菜单项,还包含菜单项。这就是我所拥有的:

<div class="cnt">
    <div class="menu-item" ng-click="toggle(1); open1=!open1">
        <md-list layout="row" layout-padding="" class="layout-row" layout-align="start center" flex> 
            <span class="title flex" flex=""> Menu Item</span>
            <i class="fa fa-chevron-down" ng-class="{'rotate180': open1, 'rotate-back': !open1}"></i>
        </md-list>
        <div class="sub-menu" ng-animate="'animate'" >
            <md-menu-item ng-if="menuIsOpen===1" ng-repeat="item in data"  >
                <md-button>
                    <div layout="row" flex="">
                        <a ui-sref="{{item.link}}">
                            <p flex=""><i class="fa fa-{{item.icon}}"></i> {{item.title}}</p>
                        </a>
                    </div>
                </md-button>
            </md-menu-item>
        </div>
    </div>
    <div class="menu-item" ng-click="toggle(2); open2=!open2">
        <md-list layout="row" layout-padding="" class="layout-row" layout-align="start center" flex> 
            <span class="title flex" flex=""> Menu Item 2</span>
            <i class="fa fa-chevron-down" ng-class="{'rotate180': open2, 'rotate-back': !open2}"></i>
        </md-list>
        <div class="sub-menu" ng-animate="'animate'" >
            <md-menu-item ng-if="menuIsOpen===2" ng-repeat="item in data2">
                <md-button>
                    <div layout="row" flex="">
                        <a ui-sref="{{item.link}}">
                            <p flex=""><i class="fa fa-{{item.icon}}"></i> {{item.title}}</p>
                        </a>
                    </div>
                </md-button>
            </md-menu-item>
        </div>
    </div>
</div>  

使用如下所示的json文件:

$scope.data = 
    [{
        title: 'Home',
        icon: 'home',
        link: '/page1/'
    }, {
        title: 'Email Us',
        icon: 'envelope',
        link: '/page2/'
    }, {
        title: 'Profile',
        icon: 'user',
        link: '/page3/'
    }, {
        title: 'Print',
        icon: 'print',
        link: '/page4/'
    }];

$scope.data2 = 
    [{
        title: 'Home 2',
        icon: 'home',
        link: '/page1/'
    }, {
        title: 'Email Us 2',
        icon: 'envelope',
        link: '/page2/'
    }, {
        title: 'Profile 2',
        icon: 'user',
        link: '/page3/'
    }, {
        title: 'Print 2',
        icon: 'print',
        link: '/page4/'
    }];

如您所见,如果我想要2个菜单项,我必须为2个菜单项构建代码,将数据添加到json,然后运行绑定。如果我想要3,那么我必须做3次。但如果我想要20呢?理想情况下,我希望有一个单独的HTML结构,它从json中提取数据,以创建尽可能多的子菜单项,就像在json中找到的子菜单项一样多。但是我在尝试实现这个目标时遇到了问题:

这是我脑子里有意义的事情:

<div class="cnt" ng-repeat="item in data">
    <div class="menu-item" ng-click="toggle({{item.pos}}); open{{item.pos}}=!open{{item.pos}}">
        <md-list layout="row" layout-padding="" class="layout-row" layout-align="start center" flex> 
            <span class="title flex" flex=""> {{item.name}}</span>
            <i class="fa fa-chevron-down" ng-class="{'rotate180': open{{item.pos}}, 'rotate-back': !open{{item.pos}}}"></i>
        </md-list>
        <div class="sub-menu" ng-animate="'animate'" >
            <md-menu-item ng-if="menuIsOpen==={{item.pos}}" >
                <md-button>
                    <div layout="row" flex="">
                        <a ui-sref="{{item.item1[0].linkto}}">
                            <p flex=""><i class="fa fa-{{item.icon}}"></i> {{item.item1[0].title}}</p>
                        </a>
                    </div>
                </md-button>
            </md-menu-item>
        </div>
    </div>
</div>  

我有一个CODEPEN,你可以看到工作代码。

请参阅此CODEPEN以获得所需效果。这就是我现在的工作方式以及它最终应该如何运作。

谢谢费拉斯!

1 个答案:

答案 0 :(得分:1)

这个答案不是直接解决解析问题,而是解决您要实现的目标。 而不是使用open{{item.pos}}来识别导致解析错误的菜单项,而是使用menuIsOpen来保存切换项的位置。基于期望的效果.. codepen sample

脚本添加

//Not needed
// $scope.open1 = false; //initial value
//$scope.open2 = false; //initial value
//$scope.open3 = false; //initial value
//$scope.open4 = false; //initial value

$scope.toggle = function(itemPos) {
    if ($scope.menuIsOpen === itemPos) {
        $scope.menuIsOpen = 0; 
    }
    else {
        $scope.menuIsOpen = itemPos;  
    }
}

html:只需要切换我们传递位置属性的item

<div class="cnt" ng-repeat="item in data">
    <div class="menu-item" ng-click="toggle(item.pos);">
        <md-list layout="row" layout-padding="" class="layout-row" layout-align="start center" flex> 
            <span class="title flex" flex=""> {{item.name}}</span>
            <i class="fa fa-chevron-down" ng-class="{'rotate180': item.pos==menuIsOpen, 'rotate-back': !menuIsOpen}"></i>
        </md-list>



        <div class="sub-menu" ng-animate="'animate'" >
            <md-menu-item ng-if="menuIsOpen===item.pos" >
                <md-button>
                    <div layout="row" flex="">
                        <a ui-sref="{{item.item1[0].linkto}}">
                            <p flex=""><i class="fa fa-{{item.icon}}"></i> {{item.item1[0].title}} a</p>
                        </a>
                    </div>
                </md-button>
            </md-menu-item>
        </div> 
    </div>
</div>

告诉我们

更新:根据您的评论,当前设置仅处理位置0处的项目(仅1项)。 JSON(如果你没有控制权)并且你需要显示item1 item2等..你可以通过遍历整个对象来扩展ng-repeat并只迭代ARRAYS。这不是最佳解决方案,只是一种解决方案.. ... ...

如果阵列中有另一个链接数组......此解决方案将无效。

HTML

<div class="sub-menu" ng-animate="'animate'" >
    <div ng-repeat='(k,v) in item track by $index'>
        <div ng-if="isArray(v)">
            <md-menu-item ng-if="menuIsOpen===item.pos" ng-repeat='v1 in v track by $index'>                        
                <md-button>
                    <div layout="row" flex="">
                        <a ui-sref="{{v1.linkto}}">
                            <p flex=""><i class="fa fa-{{v1.icon}}"></i> {{v1.title}}</p>
                        </a>
                    </div>
                </md-button>    
            </md-menu-item>
        </div>
    </div>              
</div> 

脚本

$scope.isArray = function(val) {
    return Array.isArray(val);
}