Angular-strap $affix 服务实例化问题

Angular-strap $affix service instantiation issue

我正在尝试使用 Angular-strap 的 $affix 服务以编程方式将词缀行为附加到 3 个不同的元素;其中两个必须响应目标浏览器是否大致为桌面宽度或更大(在这种情况下它们不得附加),第三个必须始终附加。一个复杂的因素是接收设备是桌面浏览器还是移动设备(以及所述移动设备是横向还是纵向模式),因为各种设备断点需要进行风格调整,这会导致变化这三个元素的词缀偏移量。

为此,我设法整理了一些逻辑来处理这些不同的情况,为了保持理智,我在附加到我的 [=34= 的自己的指令中找到了我使用 $affix 的逻辑] 应用程序。我还在自己的指令中隔离了用于检测 orientationchange 事件的逻辑,并且在我的词缀指令中,我有一个回调设置来触发 orient::change,它调用我的 handleFixes() 函数,该函数又调用我的助手函数(重新计算适当的偏移量),然后在每个附加元素上调用 $affix() 以更新其行为。

理论上这应该可以正常工作。实际上,$affix 服务似乎无法将回调附加到 "scroll"、"click" 或 "resize" 事件,因为它期望 targetEl 是一个元素,但它是未定义的。因此,$affix 根本不起作用。

认为 发生的事情是我的指令定义没有正确地将预期的目标元素(BODY 标签)传达给 $affix,但这可能还没有结束.

这是我的指令定义已编辑:

// N.B. Deliberate mis-spelling of "affix" below
searchFilter.directive('aptAfix', function($affix, $window) {

    var afixDirectiveObject = {

        link: function(scope, element, attrs) {

            // Helpers:
            var onDesktop = function () {
                    var win = $(window),
                        windowWidth = win.width(),
                        minDesktopWidth = 959;
                    return (windowWidth > minDesktopWidth);
                },

                getDevClass = function () {
                    var win = $(window),
                        winWidth = win.width(),
                        minDesktopWidth = 959;

                    if (winWidth > minDesktopWidth) {
                        return "desktop";
                    } else {
                        return "device";
                    }
                },

                // Affix-specific logic
                getFirstNavOffset = function () {
                    /* This nav hides at narrower breakpoints; so we need to know if it's visible; if so, we just return its current offset; if not, we determine its current offset relative to the secondary nav */

                    var visible = $('.primary-nav-wrap').is(':visible'),
                        second, secondOff, out;

                    if (getDevClass() === "desktop") {
                        out = 100000;
                    } else {
                        second = $('.secondary-nav-wrap');
                        secondOff = second.offset();
                        if (secondOff && secondOff.top) {
                            out = secondOff.top + (visible ? 40 : 10);
                        } else {
                            out = 0;
                        }
                    }
                    // Transform answer into string; used to prevent $affix from trying to call .match() on a numeric offset (causing borkage):
                    return out+"";
                },

                getSecondNavOffset = function () {
                    var second, secondOff, out;

                    if (getDevClass() === "desktop") {
                        out = 100000;
                    } else {
                        second = $('.secondary-nav-wrap');
                        secondOff = second.offset();
                        if (secondOff && secondOff.top) {
                            out = secondOff.top + 10;
                        } else {
                            out = 0;
                        }
                    }
                    return out+"";
                },

                getLockbarOffset = function () {
                    var lock = $('#lockbar'),
                        lockOff = lock.offset(),
                        out;

                    if (lockOff && lockOff.top) {
                        out = lockOff.top + (onDesktop() ? 60 : 30);
                    } else {
                        out = 0;
                    }
                    return out+"";
                },

                // Our utility function for running everything; will run
                // @ start & on orient::change events
                handleFixes = function () {
                    var win = angular.element($window),
                        e1 = angular.element('.primary-nav-wrap'),
                        e2 = angular.element('.secondary-nav-wrap'),
                        e3 = angular.element('#lockbar'),

                        e1Data = { offsetTop: getFirstNavOffset(), target: win },
                        e2Data = { offsetTop: getSecondNavOffset(), target: win },
                        e3Data = { offsetTop: getLockbarOffset(), target: win };

                    // EVERYTHING WORKS GREAT *UP TO THIS POINT*
                    // NOW WE MUST $affix() ELEMENTS!

                    $affix(e1, e1Data);
                    $affix(e2, e2Data);
                    $affix(e3, e3Data);
                };

            /* If you get "orient::change", update fixatives' offsets */
            scope.$on('orient::change', function() {
                handleFixes();
            });

            /* Trip our call to activate  */
            handleFixes();
        }
    };

    return afixDirectiveObject;
});

FTR,我是 运行 此代码 Angular 1.2.23 & Angular-strap 2.1.0.

提前感谢您的任何建议或见解。

哎呀,我走错了路。最初我发现我似乎没有目标元素的原因是我没有明确地将 "target" 选项传递给 $affix()。假设这是一个合适的目标,我尝试使用 $('body').

当很明显这仍然没有达到预期的效果时——也就是说,尽管控制台日志中没有任何错误,但我想添加到页面上的任何内容实际上都没有添加到页面上—— - 我决定弄清楚 bs-affix 是如何工作的,在源代码中找到了它的定义,瞧!很明显,它尝试解析提供的目标元素,但缺少它解析为 "angular.element($window)"。显然我的指令中没有现成的 $window ,所以在将它与 $affix 服务一起添加到我的注入参数中后,我用它代替了 "$('body')" 并且事情是现在按预期工作。

我希望这对任何希望使用 $affix 服务来为任何使用 Angular-strap 附加的重要元素的人有所帮助。