I am trying to build a side navigation menu, but want to dynamically populate its items based on the state of the DOM (i.e. <section>
s in my DOM).
However, I have some ng-if
s applied to various <section>
s that are based on scope variables that are retrieved via AJAX ($http.get
). So when the directive is compiled (or linked), these scope variables have not yet been retrieved and the ng-if
s are not yet stable (they are evaluated as if the variables are undefined
).
Main 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>
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;
// 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'
};
}
What is the best way to access DOM elements on the page after ng-if
expressions have been stabilized? I was thinking $timeout
but wouldn't really know what a "safe value" would be.
Or can/should I somehow use $watch
? Is there a way to get ctrl.sections
to dynamically update?