在 ng-if 编译后访问指令中的 DOM 个元素
Accessing DOM elements in directive after ng-if compiles
我正在尝试构建侧边导航菜单,但想动态地根据DOM(即<section>
的状态填充其项目在我的 DOM).
但是,我有一些 ng-if
应用于各种 <section>
,它们基于通过 AJAX 检索的范围变量 ($http.get
)。因此,当指令被编译(或链接)时,这些范围变量尚未被检索并且 ng-if
还不稳定(它们被评估为好像变量是 undefined
)。
主要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'
};
}
在 ng-if
表达式稳定后,访问页面 上的 DOM 元素的最佳方法是什么?我在想 $timeout
但真的不知道 "safe value" 会是什么。
或者can/should我不知何故使用$watch
?有没有办法让ctrl.sections
动态更新?
像这样使用link函数:
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;});
}
};
}
所以 $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'
};
}
我正在尝试构建侧边导航菜单,但想动态地根据DOM(即<section>
的状态填充其项目在我的 DOM).
但是,我有一些 ng-if
应用于各种 <section>
,它们基于通过 AJAX 检索的范围变量 ($http.get
)。因此,当指令被编译(或链接)时,这些范围变量尚未被检索并且 ng-if
还不稳定(它们被评估为好像变量是 undefined
)。
主要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'
};
}
在 ng-if
表达式稳定后,访问页面 上的 DOM 元素的最佳方法是什么?我在想 $timeout
但真的不知道 "safe value" 会是什么。
或者can/should我不知何故使用$watch
?有没有办法让ctrl.sections
动态更新?
像这样使用link函数:
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;});
}
};
}
所以 $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'
};
}