2

私は1つの質問に苦労していますが、なぜそれが起こるのか分かりません.

モジュール (portfolioModule)、サービス (Menu)、ディレクティブ (niMenu) があります。ディレクティブは、メニュー項目とそのサブ項目をレンダリングする必要があります。

HTML:

<div ng-app="portfolioModule">
    <script id="menuItem" type="text/ng-template">
    <li>
        <a>{{item.name}}</a>
        <ul>
            <li ng-repeat="item in menu.getKids(item.id)" ng-include="'menuItem'"></li>
        </ul>
    </li>
    </script>

    <div>
        <div ni-menu="test">test1</div>
    </div>
</div>

JavaScript:

var portfolioModule = angular.module('portfolioModule', []);

portfolioModule.factory('Menu', function() {
        var items = [
            {
                "parent_id": null,
                "id": 1,
                "name": "foo"
            }, {
                "parent_id": 1,
                "id": 2,
                "name": "foo-bar"
            }
        ];
        this.getKids = function(parent_id) {
            var result = [];
            parent_id = parent_id || null;

            console.log('getKids', parent_id);
            angular.forEach(items, function(value) {
                if (value.parent_id === parent_id) {
                    result.push(value);
                }
            });
            return result;
        };

        return this;
    }
);

portfolioModule.directive('niMenu', function(Menu) {
        var niMenu;
        return niMenu = {
            template: '<ul ng-include="\'menuItem\'" ng-repeat="item in menu.getKids()"></ul>',
            restirt: 'A',
            link: function(scope, element, attrs) {
                console.log('link');
                scope.menu = Menu;
            }
        };
    }
);

実際のデモ: http://jsfiddle.net/VanSanblch/Ng7ef

html では、ni-menu で niMenu を呼び出します。ディレクティブには、Menu-service をモジュールのスコープに入れるテンプレートとリンク関数があります。ディレクティブのテンプレートでは、Menu.getKids() を使用して、すべての最上位アイテムを取得します。後で、ng-include で使用されるテンプレートで、Menu.getKids(item.id) を呼び出し、特定のアイテムのすべての子を取得します。

細かい点を除いて、すべてがうまく機能します。コンソールを開くと、予想よりもはるかに多くの getKids の呼び出しがあることがわかります。たとえば、要素が 2 つの配列の場合、getKids 呼び出しの回数は 9 回です。

なぜそれが起こるのか誰か説明できますか?

4

1 に答える 1

6

複数回実行する理由は、ダイジェスト サイクルがそのように機能するためです。変更がなくなるまで、すべてのビュー式 (ngRepeat に渡すものなど) を継続的に実行します。詳細については、この回答を参照しください。

ngRepeat を使用する場合、パフォーマンスに悪影響を与えるため、通常、関数からデータを取得することは避けたいと考えます。データが変更されていないのに、なぜ同じ関数を複数回呼び出すのですか? より良いアプローチは、コントローラー (またはこの場合はディレクティブ) で関数を実行し、結果をスコープに保存することです。そのため、ngRepeatng-repeat="item in items"ng-repeat="item in getItems()".

残念ながら、これは、ディレクティブが機能する方法を再構築する必要があることを意味します。とにかく、ディレクティブを少し単純に書き直すことができるため、これは良い考えであることがわかります。たとえば、ngInclude は必要ありません。

2 つのテンプレートがあるため、必要なことは 2 つのディレクティブを作成することです。1 つはメニュー全体を表し、もう 1 つは子アイテム (子アイテムを持つことができます) を表します。ディレクティブは、最menu上位のメニュー項目で繰り返し、menuItemそれぞれに を描画する必要があります。ディレクティブはmenuItem子をチェックし、必要に応じてさらにmenuItems を使用してそれらを繰り返す必要があります。Andy Joslin によって作成された、再帰的なディレクトリを実現する方法の例を次に示します: http://plnkr.co/edit/T0BgQR

このようなものを実装するには、この質問の範囲を超えていますが、助けが必要な場合は、それを突き刺して新しい質問を投稿してください。

幸運を!

于 2013-03-07T06:09:06.490 に答える