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

时间:2015-03-31 20:07:11

标签: angularjs angular-strap

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

为此,我已经设法将一些逻辑用于处理这些不同的情况,并且为了保持理智,我找到了在我自己的Angular应用程序附带的指令中使用$ affix的逻辑。我还在其自己的指令中隔离了用于检测orientationchange事件的逻辑,并且在我的词缀指令中,我有一个回调设置来在orient :: change上跳转,它调用我的handleFixes()函数,后者又调用我的辅助函数(重新计算正确的偏移量)然后在每个附加元素上调用$ affix()来更新其行为。

从理论上讲,这应该可行。在实践中,看起来$ affix服务无法将回调附加到“滚动”,“单击”或“调整大小”事件,因为它期望targetEl是一个元素,但它是未定义的。结果,$ affix根本不起作用。

认为正在发生的事情是我的指令定义没有正确地将预期的目标元素(BODY标签)传达到$ affix中,但这可能不是它的结尾。

这是我的指令定义 EDITED

// 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和&amp ;;运行此代码。 Angular-strap 2.1.0。

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

1 个答案:

答案 0 :(得分:1)

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

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

我希望这对任何想要使用$ affix服务的人都有用,因为任何非平凡的元素都会附加Angular-strap。