178

Web アプリのツリー構造でデータを表示しようとしています。このタスクに Angular を使用したいと考えていました。

ng-repeat を使用すると、ノードのリストを反復処理できるように見えますが、特定のノードの深さが増加したときにネストを行うにはどうすればよいですか?

次のコードを試しましたが、HTML の自動エスケープにより、これが機能しません。さらに、最後の ul タグが間違った場所にあります。

私は、この問題について完全に間違った方法で取り組んでいると確信しています。

何か案は?

4

14 に答える 14

236

このフィドルを見てください

オリジナル: http: //jsfiddle.net/brendanowen/uXbn6/8/

更新: http: //jsfiddle.net/animaxf/uXbn6/4779/

これにより、usingAngularを表示する方法がわかりますtree like structure。これは、htmlで再帰を使用するようなものです。

于 2012-08-08T08:56:15.910 に答える
77

Bootstrap CSS を使用している場合...

Bootstrap の「nav」リストに基づいて、AngularJS 用の単純な再利用可能なツリー コントロール (ディレクティブ) を作成しました。インデント、アイコン、アニメーションを追加しました。構成には HTML 属性が使用されます。

再帰は使用しません。

私はそれをangular-bootstrap-nav-treeと呼びました(キャッチーな名前だと思いませんか?)

ここに例があり、ソースはここにあります。

于 2013-08-18T16:54:00.227 に答える
18

angular-ui-treeは私にとって良い仕事をしているようです

于 2014-05-06T15:46:30.390 に答える
15

再帰ディレクティブを使用した例を次に示します: http://jsfiddle.net/n8dPm/ https://groups.google.com/forum/#!topic/angular/vswXTes_FtM から取得

module.directive("tree", function($compile) {
return {
    restrict: "E",
    scope: {family: '='},
    template: 
        '<p>{{ family.name }}</p>'+
        '<ul>' + 
            '<li ng-repeat="child in family.children">' + 
                '<tree family="child"></tree>' +
            '</li>' +
        '</ul>',
    compile: function(tElement, tAttr) {
        var contents = tElement.contents().remove();
        var compiledContents;
        return function(scope, iElement, iAttr) {
            if(!compiledContents) {
                compiledContents = $compile(contents);
            }
            compiledContents(scope, function(clone, scope) {
                     iElement.append(clone); 
            });
        };
    }
};
});
于 2013-05-27T21:28:43.533 に答える
12

これはもう少し完全なようです: https://github.com/dump247/angular.tree

于 2013-03-04T16:53:47.927 に答える
5

元のソースに基づいた別の例では、サンプル ツリー構造が既に配置されており (IMO でどのように機能するかを簡単に確認できます)、ツリーを検索するためのフィルターを使用しています。

JSFiddle

于 2013-03-23T23:32:41.040 に答える
4

非常に多くの優れた解決策がありますが、いずれも何らかの形で物事を複雑にしすぎているように感じます。

@Mark Lagendijk の awnser のシンプルさを再現したものを作成したかったのですが、ディレクティブでテンプレートを定義せずに、「ユーザー」が HTML でテンプレートを作成できるようにしました...

https://github.com/stackfull/angular-tree-repeatなどからアイデアを取り入れて...プロジェクトを作成することになりました: https://github.com/dotJEM/angular-tree

これにより、次のようなツリーを構築できます。

<ul dx-start-with="rootNode">
  <li ng-repeat="node in $dxPrior.nodes">
    {{ node.name }}
    <ul dx-connect="node"/>
  </li>
</ul>

私にとっては、異なる構造のツリーに対して複数のディレクティブを作成するよりもクリーンです....本質的に、上記のツリーを呼び出すのは少し間違っています。@ganaraj の「再帰テンプレート」の awnser からより多くのものを取り出しますが、ツリーが必要な場所にテンプレートを定義します。

(スクリプトタグベースのテンプレートでそれを行うこともできますが、それでも実際のツリーノードのすぐ外側に配置する必要があり、それでも少しぎこちなく感じます...)

別の選択のためにここに残しました...

于 2014-06-09T16:20:45.120 に答える
3

Angular-Ui-Tree でAngular-Tree-DnDサンプルを試すことができますが、私は編集し、テーブル、グリッド、リストとの互換性があります。

  • ドラッグ&ドロップが可能
  • リストの拡張機能ディレクティブ(next、prev、getChildren、...)
  • データをフィルタリングします。
  • オーダーバイ (ver)
于 2015-05-29T16:31:37.607 に答える
0

そのために angular-recursion-injector を使用できます: https://github.com/knyga/angular-recursion-injector

条件付けで無制限の深さのネスティングを行うことができます。必要な場合にのみ再コンパイルを行い、正しい要素のみをコンパイルします。コードに魔法はありません。

<div class="node">
  <span>{{name}}</span>

  <node--recursion recursion-if="subNode" ng-model="subNode"></node--recursion>
</div>

他のソリューションよりも高速かつ簡単に機能することを可能にするものの1つは、「--recursion」サフィックスです。

于 2015-06-12T10:22:49.307 に答える
0

ツリー構造が大きい場合、Angular (1.4.x まで) は再帰テンプレートのレンダリングが非常に遅くなります。これらの提案をいくつか試した後、単純な HTML 文字列を作成し、それを使用ng-bind-htmlして表示することにしました。もちろん、これは Angular の機能を使用する方法ではありません

最低限の再帰関数を次に示します (最小限の HTML を使用)。

function menu_tree(menu, prefix) {
    var html = '<div>' + prefix + menu.menu_name + ' - ' + menu.menu_desc + '</div>\n';
    if (!menu.items) return html;
    prefix += menu.menu_name + '/';
    for (var i=0; i<menu.items.length; ++i) {
        var item = menu.items[i];
        html += menu_tree(item, prefix);
    }
    return html;
}
// Generate the tree view and tell Angular to trust this HTML
$scope.html_menu = $sce.trustAsHtml(menu_tree(menu, ''));

テンプレートでは、次の 1 行だけが必要です。

<div ng-bind-html="html_menu"></div>

これにより、Angular のデータ バインディングがすべてバイパスされ、再帰的なテンプレート メソッドのほんのわずかな時間で HTML が表示されます。

次のようなメニュー構造 (Linux ファイル システムの部分的なファイル ツリー) を使用します。

menu = {menu_name: '', menu_desc: 'root', items: [
            {menu_name: 'bin', menu_desc: 'Essential command binaries', items: [
                {menu_name: 'arch', menu_desc: 'print machine architecture'},
                {menu_name: 'bash', menu_desc: 'GNU Bourne-Again SHell'},
                {menu_name: 'cat', menu_desc: 'concatenate and print files'},
                {menu_name: 'date', menu_desc: 'display or set date and time'},
                {menu_name: '...', menu_desc: 'other files'}
            ]},
            {menu_name: 'boot', menu_desc: 'Static files of the boot loader'},
            {menu_name: 'dev', menu_desc: 'Device files'},
            {menu_name: 'etc', menu_desc: 'Host-specific system configuration'},
            {menu_name: 'lib', menu_desc: 'Essential shared libraries and kernel modules'},
            {menu_name: 'media', menu_desc: 'Mount point for removable media'},
            {menu_name: 'mnt', menu_desc: 'Mount point for mounting a filesystem temporarily'},
            {menu_name: 'opt', menu_desc: 'Add-on application software packages'},
            {menu_name: 'sbin', menu_desc: 'Essential system binaries'},
            {menu_name: 'srv', menu_desc: 'Data for services provided by this system'},
            {menu_name: 'tmp', menu_desc: 'Temporary files'},
            {menu_name: 'usr', menu_desc: 'Secondary hierarchy', items: [
                {menu_name: 'bin', menu_desc: 'user utilities and applications'},
                {menu_name: 'include', menu_desc: ''},
                {menu_name: 'local', menu_desc: '', items: [
                    {menu_name: 'bin', menu_desc: 'local user binaries'},
                    {menu_name: 'games', menu_desc: 'local user games'}
                ]},
                {menu_name: 'sbin', menu_desc: ''},
                {menu_name: 'share', menu_desc: ''},
                {menu_name: '...', menu_desc: 'other files'}
            ]},
            {menu_name: 'var', menu_desc: 'Variable data'}
        ]
       }

出力は次のようになります。

- root
/bin - Essential command binaries
/bin/arch - print machine architecture
/bin/bash - GNU Bourne-Again SHell
/bin/cat - concatenate and print files
/bin/date - display or set date and time
/bin/... - other files
/boot - Static files of the boot loader
/dev - Device files
/etc - Host-specific system configuration
/lib - Essential shared libraries and kernel modules
/media - Mount point for removable media
/mnt - Mount point for mounting a filesystem temporarily
/opt - Add-on application software packages
/sbin - Essential system binaries
/srv - Data for services provided by this system
/tmp - Temporary files
/usr - Secondary hierarchy
/usr/bin - user utilities and applications
/usr/include -
/usr/local -
/usr/local/bin - local user binaries
/usr/local/games - local user games
/usr/sbin -
/usr/share -
/usr/... - other files
/var - Variable data
于 2015-09-16T21:44:15.673 に答える
0

はい、間違いなく可能です。ここでの質問はおそらくAngular 1.xを想定していますが、将来の参考のためにAngular 2の例を含めています:

概念的には、再帰的なテンプレートを作成するだけです。

<ul>
    <li *for="#dir of directories">

        <span><input type="checkbox" [checked]="dir.checked" (click)="dir.check()"    /></span> 
        <span (click)="dir.toggle()">{{ dir.name }}</span>

        <div *if="dir.expanded">
            <ul *for="#file of dir.files">
                {{file}}
            </ul>
            <tree-view [directories]="dir.directories"></tree-view>
        </div>
    </li>
</ul>

次に、ツリー オブジェクトをテンプレートにバインドし、Angular にその魔法を働かせます。この概念は明らかに Angular 1.x にも当てはまります。

完全な例を次に示します: http://www.syntaxsuccess.com/viewarticle/recursive-treeview-in-angular-2.0

于 2015-05-30T20:55:10.423 に答える