2

サイド ナビゲーション メニューを構築しようとしていますが、DOM の状態 (つまり、DOM 内) に基づいて項目を動的に<section>設定したいと考えています。

ただし、AJAX ( ) を介して取得されるスコープ変数に基づくng-ifさまざまな に適用されるがいくつかあります。そのため、ディレクティブがコンパイル (またはリンク) されたとき、これらのスコープ変数はまだ取得されておらず、はまだ安定していません (変数が であるかのように評価されます)。<section>$http.getng-ifundefined

メイン HTML

<my-sidenav></my-sidenav>

<!-- Bunch of other content and structure -->

<section id="foo1" class="sidenav-item">...</section>
<section id="foo2" class="sidenav-item">...</section>
<section id="foo3" class="sidenav-item" ng-if="fooVar1 === fooVar2">...</section>
<section id="foo4" class="sidenav-item">...</section>
<section id="foo5" class="sidenav-item" ng-if="fooVar3 !== fooVar4">...</section>

サイドナビ HTML

<div>
    <a ng-repeat="section in ctrl.sections track by section" href="#" ng-click="ctrl.scrollTo(section)">{{section}}</a>
</div>

ディレクティブの定義

function mySidenav() {
    return {
        templateUrl: 'sidenav.html',
        controller: function() {
            var ctrl = this;

            // After template URL is linked up
            // !!! ng-if still not stable !!!
            ctrl.$postLink = function() {
                // Convert nodeList to array for easier manipulation
                var nodeList = document.querySelectorAll('.sidenav-item');
                var nodeArray = Array.prototype.slice.call(nodeList);

                // Extract section id
                ctrl.sections = nodeArray.map(function(el) {return el.id;});
            };

            ctrl.scrollTo = /*...*/
        },
        controllerAs: 'ctrl'
    };
}

式が安定化された 、ページ上の DOM 要素にアクセスする最良の方法は何ですか? ng-if私は考え$timeoutていましたが、「安全な値」が何であるかは本当にわかりません.

または、どういうわけか使用できますか/使用する必要があります$watchか? ctrl.sections動的に更新する方法はありますか?

4

2 に答える 2

0

うまく$watchCollectionいきますが、この質問は、この解決策または他の解決策に関するフィードバックのために開いたままにします。

ディレクティブ定義を次のように変更しました

function tipSidenav() {
    return {
        templateUrl: '/tip/resources/html/sidenav.html',
        controller: ['$rootScope', function($rootScope) {
            var ctrl = this;

            $rootScope.$watchCollection(
                function(scope) {
                    return getSections();
                },
                function(newValue, oldValue, scope) {
                    ctrl.sections = newValue;
                }
            );

            ctrl.scrollTo = /*...*/;

            function getSections() {
                // More efficient way of gettings IDs
                var ids = [];

                var nodeList = document.querySelectorAll('.sidenav-item');
                for (var i = 0; i < nodeList.length; i++) {
                    ids.push(nodeList[i].id);
                }

                return ids;
            }
        }],
        controllerAs: 'ctrl'
    };
}
于 2016-05-10T17:35:34.967 に答える
0

次のようにリンク機能を使用します。

function mySidenav() {
    return {
        templateUrl: 'sidenav.html',
        link: function(scope, elm) {
                // Convert nodeList to array for easier manipulation
                var nodeList = document.querySelectorAll('.sidenav-item');
                var nodeArray = Array.prototype.slice.call(nodeList);
                var sections = nodeArray.map(function(el) {return el.id;});   
        }
    };
}

http://codepen.io/nicholasabrams/pen/oxVxQa?editors=1010

于 2016-05-10T17:25:05.247 に答える