3

私は角張っていて、このようなオブジェクトを持っています。

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'}
                ]}
            ]}
        ]}
    ]
}];

これらすべてをループしたくないので、このようなものがあります。

    • 何か

       • こんにちは世界

       • ハロー オーバーフロー

       • ジョン・ドウ

          •素晴らしいタイトル

          • Google で検索

          • 私は子供です

              • 別

              • 彼は僕のお兄さん

              • 彼女は私の母です

                  • 私が子供を持つかどうかは決してわかりません

問題は、このオブジェクトがどのくらいの深さになるのか、その中に何が入っているのかわからないことです。だから私は手動でそれを行うことはできません。ng-repeat下部にあるフィドルで基本的なループを実行しましたが、これらを自動的にループしてネストされた<ul>とを作成する方法がわかりません<li>

これを達成するための最良の方法は何ですか?

デモ: http://jsfiddle.net/XtgLM/

4

3 に答える 3

8

どうぞ:

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

私はあなたのフィドルをフォークしました:

http://jsfiddle.net/c4Kp8/

実際、Master Morality のアプローチが気に入っていることを告白しなければなりませんが、カスタム ディレクティブを使用することもできます。そのルートに進む場合に知っておくべき重要なことは、現在のアイテムに子があるかどうかを手動で確認するためにアイテム レベルでインターセプトする必要があることです。その場合は、ノードのディレクティブを自分でコンパイルします。

アップデート

ただし、上記のコードには気になる点が 1 つあります。html コード (ディレクティブにインライン化されている) の重複は、コードの匂いです。template-code必要に応じて、他のディレクティブのテンプレートとして適用されるノードのコードを提供する以外は何もしない一般的なディレクティブを導入することで、非常にファンキーになり、これを修正できます。

したがって、ソリューションは次のようになります。

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

プランカー: http://jsfiddle.net/2rQWf/

于 2013-08-23T18:08:51.207 に答える
0

おそらく、反復するオブジェクトを渡す独自のディレクティブを作成する必要があるでしょう。渡されたオブジェクトにウォッチを置き、それが起動すると、ディレクティブがオンになっている要素に要素を追加する再帰関数を実行します。

ディレクティブ リンク関数の要素パラメーターから DOM 要素を取得できます。同じ要素パラメーターを使用して、明らかに DOM 要素を追加できます。

于 2013-08-23T17:39:50.603 に答える