在 ng-repeat 中循环遍历深层对象 [英] Looping through deep objects in ng-repeat

查看:27
本文介绍了在 ng-repeat 中循环遍历深层对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有角度,我有一个这样的对象.

var items = [{title: '东西',孩子们: [{ 标题:'你好世界' },{ title: '你好溢出' },{ 标题:'John Doe',孩子们:[{ title: '惊人的标题' },{ title: '谷歌它' },{标题:'我是个孩子',孩子们:[{ title: '另一个' },{ title: '他是我的兄弟' },{标题:'她是我的妈妈.',孩子们:[{title: '你永远不知道我是否会生孩子'}]}]}]}]}];

我不想遍历所有这些,所以我有这样的东西.

<块引用>

• 某事

• 你好世界

• 你好溢出

• John Doe

• 惊人的标题

• 谷歌一下

• 我是个孩子

• 另一个

• 他是我的兄弟

•她是我的妈妈

• 你永远不知道我是否会生孩子

问题是我不知道这个物体会进入多深或里面有什么.所以我无法手动完成.我在底部提供的小提琴中使用 ng-repeat 完成了一个基本循环,但我不知道如何自动循环这些并创建嵌套的 <ul>

  • 的.

    实现这一目标的最佳方法是什么?

    演示:http://jsfiddle.net/XtgLM/

    解决方案

    给你:

    html

    <ul><linested-item ng-repeat="item in items">{{item.title}}</li>

    JavaScript

    var items = [{title: '东西',孩子们: [{ 标题:'你好世界' },{ title: '你好溢出' },{ 标题:'John Doe',孩子们:[{ title: '惊人的标题' },{ title: '谷歌它' },{标题:'我是一个孩子',孩子们:[{ title: '另一个' },{ title: '他是我的兄弟' },{标题:'她是我的妈妈.',孩子们:[{title: '你永远不知道我是否会生孩子'}]}]}]}]}];var app = angular.module('app', []);app.controller('test', function( $scope ) {$scope.items = 物品;});app.directive('nestedItem', ['$compile', function($compile){返回 {限制:'A',链接:功能(范围,元素){控制台日志(元素);如果(范围.item.children){var html = $compile('<ul><li nested-item ng-repeat="item.children 中的项目">{{item.title}}</li></ul>')(范围);element.append(html);}}};}]);

    我分叉了你的小提琴:

    http://jsfiddle.net/c4Kp8/

    实际上,我必须承认我喜欢 Master Morality 的方法,但您也可以使用自定义指令.如果你走那条路线,要知道的关键是你需要在项目级别进行拦截以手动检查当前项目是否有子项,如果有,自己为节点编译指令.

    更新

    然而,在上面的代码中有一件事情应该困扰我们.html 代码的重复(在指令中内联)是一种代码异味.如果你愿意,你可以变得非常时髦并通过引入一个通用的 template-code 指令来解决这个问题,该指令不做任何其他事情,但提供应用它的节点的代码作为模板其他指令.

    那么我们的解决方案将如下所示:

    html

    <ul模板代码><linested-item ng-repeat="item in items">{{item.title}}</li>

    JavaScript

    var items = [{title: '东西',孩子们: [{ 标题:'你好世界' },{ title: '你好溢出' },{ 标题:'John Doe',孩子们:[{ title: '惊人的标题' },{ title: '谷歌它' },{标题:'我是一个孩子',孩子们:[{ title: '另一个' },{ title: '他是我的兄弟' },{标题:'她是我的妈妈.',孩子们:[{title: '你永远不知道我是否会生孩子'}]}]}]}]}];var app = angular.module('app', []);app.controller('test', function( $scope ) {$scope.items = 物品;});app.directive('templateCode', function(){返回 {限制:'A',控制器:函数(){},编译:函数(元素){element.removeAttr('模板代码');//注意:我们需要在这里修剪().否则 AngularJS 会引发异常//稍后当我们想在 $compile 函数中使用模板代码时.//请注意,我们假设一个现代浏览器//已经带有修剪功能.//使用 polyfill 很容易确保它的安全.var templateCode = element.parent().html().trim();返回函数(范围,iElement,iAttrs,控制器){控制器模板代码 = 模板代码;}}}});app.directive('nestedItem', ['$compile', function($compile){返回 {限制:'A',要求:'^模板代码',链接:功能(范围,元素,iAttr,控制器){如果(范围.item.children){scope.items = scope.item.children;var html = $compile(controller.templateCode)(scope);element.append(html);}}};}]);

    Plunker:http://jsfiddle.net/2rQWf/

    I'm in angular and i have a object like this.

    var items = [{
        title: 'Something',
        children: [
            { title: 'Hello World' },
            { title: 'Hello Overflow' },
            { title: 'John Doe', children: [
                { title: 'Amazing title' },
                { title: 'Google it' },
                { title: 'I'm a child', children: [
                    { title: 'Another ' },
                    { title: 'He\'s my brother' },
                    { title: 'She\'s my mother.', children: [
                        {title: 'You never know if I'm going to have children'}
                    ]}
                ]}
            ]}
        ]
    }];
    

    I wan't to loop through all of these so i have something like this.

        • Something

           • Hello World

           • Hello Overflow

           • John Doe

              • Amazing Title

              • Google it

              • I'm a child

                  • Another

                  • He's my brother

                  • She's my mother

                      • You never know if I'm going to have children

    The problem is I wouldn't know how deep this object will go or what's in it. so I wouldn't be able to do it manually. I have done a basic loop with ng-repeat in the fiddle provided at the bottom, but i can't figure out how I can automatically loop through these and create nested <ul>'s and <li>'s.

    What would be the best way to accomplish this?

    Demo: http://jsfiddle.net/XtgLM/

    解决方案

    Here you go:

    html

    <div ng-app="app" ng-controller="test">
       <ul>
           <li nested-item ng-repeat="item in items">{{item.title}}</li>
       </ul>         
    </div>
    

    JavaScript

    var items = [{
        title: 'Something',
        children: [
            { title: 'Hello World' },
            { title: 'Hello Overflow' },
            { title: 'John Doe', children: [
                { title: 'Amazing title' },
                { title: 'Google it' },
                { title: 'Im a child', children: [
                    { title: 'Another ' },
                    { title: 'He\'s my brother' },
                    { title: 'She\'s my mother.', children: [
                        {title: 'You never know if im going to have children'}
                    ]}
                ]}
            ]}
        ]
    }];
    
    var app = angular.module('app', []);
    
    app.controller('test', function( $scope ) {
        $scope.items = items;
    });
    
    
    app.directive('nestedItem', ['$compile', function($compile){
        return {
            restrict: 'A',
            link: function(scope, element){
            console.log(element);
                if (scope.item.children){
                    var html = $compile('<ul><li nested-item ng-repeat="item in item.children">{{item.title}}</li></ul>')(scope);
                    element.append(html);
                }
            }
        };
    }]);
    

    I forked your fiddle:

    http://jsfiddle.net/c4Kp8/

    Actually I must confess that I like Master Morality's approach but you can also go with a custom directive. The key thing to know if you go that route is that you need to intercept on the item level to manually check if the current item has children, and if so, $compile the directive for the node yourself.

    UPDATE

    However, there is one thing that should bother us in the above code. The duplication of html code (inlined in the directive) is a code smell. If you like, you can get really funky and fix this by introducing a generic template-code directive which doesn't do anything else but providing the code of the node where it is applied on as a template for other directives.

    So then our solution would look like this:

    html

    <div ng-app="app" ng-controller="test">
       <ul template-code>
           <li nested-item ng-repeat="item in items">{{item.title}}</li>
       </ul>         
    </div>
    

    JavaScript

    var items = [{
        title: 'Something',
        children: [
            { title: 'Hello World' },
            { title: 'Hello Overflow' },
            { title: 'John Doe', children: [
                { title: 'Amazing title' },
                { title: 'Google it' },
                { title: 'Im a child', children: [
                    { title: 'Another ' },
                    { title: 'He\'s my brother' },
                    { title: 'She\'s my mother.', children: [
                        {title: 'You never know if im going to have children'}
                    ]}
                ]}
            ]}
        ]
    }];
    
    var app = angular.module('app', []);
    
    app.controller('test', function( $scope ) {
        $scope.items = items;
    });
    
    app.directive('templateCode', function(){
        return {
            restrict: 'A',
            controller: function(){},
            compile: function(element){
                element.removeAttr('template-code');
                //ATTENTION: We need to trim() here. Otherwise AngularJS raises an exception
                //later when we want to use the templateCode in a $compile function. 
                //Be aware that we assume a modern browser 
                //that already ships with a trim function.
                //It's easy to secure that with a polyfill.
                var templateCode = element.parent().html().trim();
                return function(scope, iElement, iAttrs, controller){
                    controller.templateCode = templateCode;
                }
            }
        }
    });
    
    app.directive('nestedItem', ['$compile', function($compile){
        return {
            restrict: 'A',
            require: '^templateCode',
            link: function(scope, element, iAttr, controller){ 
                if (scope.item.children){
                    scope.items = scope.item.children;         
                    var html = $compile(controller.templateCode)(scope);
                    element.append(html);
                }
            }
        };
    }]);
    

    Plunker: http://jsfiddle.net/2rQWf/

    这篇关于在 ng-repeat 中循环遍历深层对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆