16

我试图弄清楚为什么affix当我更改 Angular 视图时我的 -ed 面板没有保持原样。

我已将 affix 属性直接添加到第一页(详细信息)的面板中,并将其仅留在第二页(航班)的 data-spy 中。

在一个完整的网络版本中,如果我刷新航班页面,词缀会突然启动,并在我滚动时保持不变,但如果我只是使用 Angular 导航到该页面,则不会。

当我在视图之间导航时,Bootstrap 似乎没有将词缀添加到类中。

HTML:

<div class="panel panel-primary mySidebar" id="sidebar" 
    data-spy="affix" data-offset-top="0" data-offset-bottom="200">

CSS:

.mySidebar.affix {
    position: fixed;
    top: 250px;  
}

.mySidebar.affix-bottom {
    position: absolute;
    top: auto;
    bottom: 450px;  
}

这是一个Plunker..

http://plnkr.co/edit/S0Bc50?p=preview

我在这里发现了一个类似的问题:

Twitter Bootstrap:词缀未在单页应用程序中触发

但我无法弄清楚如何将其应用于我的问题......

任何帮助都会很棒!

4

5 回答 5

13

Angular UI Utils不是评论中提到的 Angular UI Bootstrap)有一个 Scrollfix 指令,可以用来代替 Affix。我遇到了和你一样的问题,改变视图后 Affix 不起作用。我尝试将 Angular UI Scrollfix 添加到我的应用程序中,到目前为止它看起来可以满足我的需求。

这是我发现的一个有用的 Stack Overflow 帖子,其中包含更多解释和示例:Angular ui-utils scrollfix

于 2014-08-07T21:59:02.990 回答
8

如果您不想使用 UI Bootstrap 或 UI Utils 来支持普通的旧 Bootstrap 3 词缀,那么这个词缀指令包装器在我的单页 Angular 应用程序上对我很有用。我正在使用 AngularUI 路由器。

第一次加载指令时应用词缀。然后$stateChagneSuccess用这个清除它:$element.removeData('bs.affix').removeClass('affix affix-top affix-bottom');如此处所示:重置/更改引导词缀的偏移量,然后重新应用它。如果我在这里做的任何事情都很难看,请告诉我,尽管我喜欢简单并且喜欢利用默认的 Bootstrap JS 库。

myApp.directive('affix', ['$rootScope', '$timeout', function($rootScope, $timeout) {
    return {
        link: function($scope, $element, $attrs) {

            function applyAffix() {
                $timeout(function() {                   
                    $element.affix({ offset: { top: $attrs.affix } });
                });
            }

            $rootScope.$on('$stateChangeSuccess', function() {
                $element.removeData('bs.affix').removeClass('affix affix-top affix-bottom');
                applyAffix();
            });

            applyAffix();

        }
    };
}]);
于 2015-01-21T22:31:24.417 回答
4

我更喜欢挂钩原始data-spy="scroll"引导绑定 - 为了更好地从 clickdummy 迁移到生产环境 - 并将原始引导功能应用于它,因为 Angular-UI(至少对我而言)是不可接受的混乱。

(function () {
  'use strict';

  angular
    .module('app.core')
    .directive('spy', spy);


  function spy() {
    return {
      restrict: 'A',
      link: link
    };

    function link(scope, element, attrs) {

      // Dom ready
      $(function () {
        if (attrs.spy === 'affix') {
          $(element).affix({
            offset: {
              top: attrs.offsetTop || 10
              // bottom: attrs.offsetBottom || 10
            }
          });
        }
      });
    }
  }
})();
于 2015-10-02T09:21:27.827 回答
3

这是一个老问题,但我最近在将我的网站重写为 AngularJS 应用程序时偶然发现了它。我也在使用 Bootstrap Affix 插件(包括在滚动时更新活动类),并且无法找到一个与我正在寻找的非常相似的插件,所以我编写了自己的指令。

在行动中看到它:http: //bobbograph.com/#/api

注意:提供给指令的值是顶部偏移量。

JavaScript:

https://github.com/robertmesserle/Bobbograph/blob/v3/www/js/site.js#L102

app.directive('rmAffix', function ($window) {
  var body = document.body,
      win = document.defaultView,
      docElem = document.documentElement,
      isBoxModel = (function () {
        var box = document.createElement('div'),
            isBoxModel;
        box.style.paddingLeft = box.style.width = "1px";
        body.appendChild(box);
        isBoxModel = box.offsetWidth == 2;
        body.removeChild(box);
        return isBoxModel;
      })();
  function getTop (element) {
    var box = element.getBoundingClientRect(),
        clientTop  = docElem.clientTop  || body.clientTop  || 0,
        scrollTop  = win.pageYOffset || isBoxModel && docElem.scrollTop || body.scrollTop;
    return box.top + scrollTop - clientTop;
  }
  return function ($scope, $element, $attrs) {
    var offset = $scope.$eval($attrs.rmAffix),
        elemTop = getTop($element[0]),
        $links = $element.find('li'),
        linkTops = [];
    angular.forEach($links, function ($link) {
      var $a = angular.element($link).find('a'),
          href = $a.attr('href').substr(1),
          target = document.getElementById(href),
          elemTop = getTop(target);
      linkTops.push(elemTop);
      $a.on('click', function (event) {
        window.scrollTo(0, elemTop - offset);
        event.preventDefault();
      });
    });
    angular.element($window).on('scroll', function (event) {
      var top = window.pageYOffset,
          index;
      if (top > elemTop - offset) $element.addClass('affix');
      else $element.removeClass('affix');
      //-- remove selected class from all links
      $links.removeClass('active');
      //-- find the closest element
      for (index = 1; index < linkTops.length; index++) {
        if (linkTops[index] - 100 > top) break;
      }
      angular.element($links[index - 1]).addClass('active');
    });
  };
});

HTML (翡翠)

https://github.com/robertmesserle/Bobbograph/blob/v3/www/api.jade#L288

ul.nav.nav-stacked.nav-pills(rm-affix=70)
  li.active: a( href="#basic" ) Basic Usage
  li: a( href="#options"   ) Options
  li: a( href="#data"      ) Data
  li: a( href="#padding"   ) Padding
于 2014-10-14T16:35:56.663 回答
2

它不起作用,因为特定的事件不会被绑定到哪个词缀上。在您的情况下的单页应用程序中,页面仅加载一次,因此绑定到页面加载和类似事件的任何逻辑都会失败。如果您重新加载页面,一切都会正常工作。

解决方案是使用角度化的方式。其中一条评论建议尝试使用 angular-strap,因为它具有用于完全相同目的的 affix 指令。

我遇到了类似的情况并最终使用了MacGyver它工作得非常好并且易​​于使用。

于 2014-06-29T18:57:09.793 回答