javascript - Angular Directive(指令) : Is there a better way than '$timeout' to get info about DOM elements created in "compile" function?

标签 javascript angularjs angularjs-directive compilation timeout

我创建了一个自定义 <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/

相关文章:

javascript - 需要 12 小时格式而不显示 AM/PM Timepicker

javascript - 如何在谷歌地图中获取降落点纬度和经度

javascript - 导航丸导航 html 需要双击才能更改事件选项卡类别

angularjs - 在 ng-click 上使用按钮进行过滤和取消过滤

angularjs - 如何创建复制现有指令的可重用 AngularJs 指令

angularjs - Angular 指令需要相同的元素

javascript - 如果基于可用的类别,则获取跨度索引

javascript - jQuery 弹出窗口与 Asp.Net MVC 不能很好地配合

javascript - 无穷大是javascript中的某个数字吗?

javascript - 为一个(部分)网页实现不同的布局