我创建了一个自定义 <select>
使用指令的下拉元素,其行为的一个方面是自动调整大小,其中元素适合三种大小之一,具体取决于其最宽选项的宽度。
但是,因为选项填充在 compile
中基于来自 Controller 的数据的功能,我无法确定选项列表的宽度,直到稍后,在预链接或后链接功能中,但我能够检查宽度的唯一方法是等待列表通过将我的后链接函数嵌套在 0 毫秒计时器中来填充。
这是我通过各种资源找到的解决方案,但我觉得可能有更优雅的方法?
这是我的指令代码:
.directive('slidingSelect', function($timeout) {
return {
restrict: 'E',
compile: function(element, attrs) {
var selecting = attrs.selecting;
// ng-repeated options come from selecting attr
var dropDownList = $('<div class="sliding-select-list"></div>');
dropDownList.append('<div class="sliding-select-option" ng-repeat="item'+
' in home.'+selecting+'.options">{{item.name}}</div>');
element.append(dropDownList);
element.click(
// Function to slide up/down the list as necessary
function() {
/* omitted */
});
// With compile defined, can return post-link functions
return function(scope, element, attrs) {
$timeout(function() {
var list = element.find('.sliding-select-list');
var options = list.children();
// Find natural width of list, set data-width, then list to match
var listWidth = list.width();
element.attr('data-width', (listWidth>180?'large':(listWidth>100?'medium':'small')));
// Hide list
element.addClass('closed');
}, 0);
};
}
};
最佳答案
当 javascript 运行时,浏览器会暂停 DOM 渲染,直到 javascript 执行完成。因此,当您将元素添加到 DOM 时,浏览器知道它有新的项目要绘制并且它必须重新绘制屏幕,但是在 javascript 完成执行之前它不能这样做。
设置超时的作用是让浏览器在调用任何为超时注册的函数之前重新获得控制权,从而允许它在运行超时代码之前重新绘制屏幕并计算选项列表的宽度。
我敢肯定它比我描述的要复杂得多,但以这种方式思考它有助于我更好地理解 javascript 和 DOM 如何协同工作。
我想不出更好的方法来完成您正在尝试做的事情。我一直都是这样做的。
关于javascript - Angular Directive(指令) : Is there a better way than '$timeout' to get info about DOM elements created in "compile" function?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27956348/