Web アプリのツリー構造でデータを表示しようとしています。このタスクに Angular を使用したいと考えていました。
ng-repeat を使用すると、ノードのリストを反復処理できるように見えますが、特定のノードの深さが増加したときにネストを行うにはどうすればよいですか?
次のコードを試しましたが、HTML の自動エスケープにより、これが機能しません。さらに、最後の ul タグが間違った場所にあります。
私は、この問題について完全に間違った方法で取り組んでいると確信しています。
何か案は?
このフィドルを見てください
オリジナル: http: //jsfiddle.net/brendanowen/uXbn6/8/
更新: http: //jsfiddle.net/animaxf/uXbn6/4779/
これにより、usingAngularを表示する方法がわかりますtree like structure。これは、htmlで再帰を使用するようなものです。
angular-ui-treeは私にとって良い仕事をしているようです
再帰ディレクティブを使用した例を次に示します: 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); 
            });
        };
    }
};
});
これはもう少し完全なようです: https://github.com/dump247/angular.tree
非常に多くの優れた解決策がありますが、いずれも何らかの形で物事を複雑にしすぎているように感じます。
@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 からより多くのものを取り出しますが、ツリーが必要な場所にテンプレートを定義します。
(スクリプトタグベースのテンプレートでそれを行うこともできますが、それでも実際のツリーノードのすぐ外側に配置する必要があり、それでも少しぎこちなく感じます...)
別の選択のためにここに残しました...
Angular-Ui-Tree でAngular-Tree-DnDサンプルを試すことができますが、私は編集し、テーブル、グリッド、リストとの互換性があります。
そのために 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」サフィックスです。
ツリー構造が大きい場合、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
はい、間違いなく可能です。ここでの質問はおそらく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