I am currently working on creating a dynamic side navigation menu that will populate its items based on the state of the DOM, specifically the <section>
elements in my document.
The challenge I am facing is that I have applied some ng-if
directives to certain <section>
elements, and these directives are dependent on scope variables that are fetched via AJAX using $http.get
. As a result, when the directive is compiled or linked, these scope variables have not yet been retrieved and the ng-if
conditions are unstable as they evaluate as if the variables are undefined
.
Main HTML
<my-sidenav></my-sidenav>
<!-- Various 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>
Sidenav HTML
<div>
<a ng-repeat="section in ctrl.sections track by section" href="#" ng-click="ctrl.scrollTo(section)">{{section}}</a>
</div>
Directive Definition
function mySidenav() {
return {
templateUrl: 'sidenav.html',
controller: function() {
var ctrl = this;
// Once template URL is linked
// !!! 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'
};
}
Is there a preferred method to access DOM elements on the page only after the ng-if
expressions have stabilized? I was considering using $timeout
, but I'm unsure of what would be a safe delay value.
Alternatively, could I utilize $watch
? Is there a way to ensure that ctrl.sections
dynamically updates?