Bootstrap data-spy = "affix" не работает на Angular Просмотр изменений

Я пытаюсь понять, почему моя панель affix не была оставлена ​​при изменении моего представления Angular.

Я добавил свойство affix непосредственно на панель на первой странице (подробности) и оставил ее в шпионах данных только на второй странице (полеты).

В полномасштабной веб-версии, если я обновляю страницу рейсов, внезапно аффикс запускается и остается при прокрутке, но нет, если я просто перейду на страницу с помощью 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: Affix не запускается в одностраничном приложении

Но я не мог понять, как применить это к моей проблеме здесь...

Любая помощь будет замечательной!

Ответы

Ответ 1

Angular UI Utils ( не Angular UT Bootstrap, как упоминалось в комментариях) директива Scrollfix, которая может использоваться вместо Affix. У меня была та же проблема, что и у вас с Affix, не работающим после смены просмотров. Я попробовал добавить Angular UI Scrollfix в мое приложение, и, похоже, он будет соответствовать моим потребностям.

Вот полезный пост, который я нашел с большим количеством объяснений и примеров: Angular ui-utils scrollfix.

Ответ 2

Если вы не хотите использовать UI Bootstrap или UI Utils в пользу простого старого ассемблера Bootstrap 3, эта оболочка директивы affix работает хорошо для меня на моей странице angular. Я использую AngularUI Router.

Применить аффикс при первой загрузке директивы. Затем очистите его на $stateChagneSuccess следующим образом: $element.removeData('bs.affix').removeClass('affix affix-top affix-bottom');, как показано здесь: Сброс/изменение смещения бутстрап-аффикса, а затем повторно применить его. Дайте мне знать, если что-то, что я здесь делаю, болезненно уродливое, хотя мне нравится простота, и мне нравится использовать стандартную загрузку JS lib.

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();

        }
    };
}]);

Ответ 3

Я предпочитаю привязывать оригинальные привязки к бутстрапу data-spy="scroll" - для лучшей миграции из clickdummy в production - и применять к нему исходные функции начальной загрузки, потому что 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
            }
          });
        }
      });
    }
  }
})();

Ответ 4

Это старый вопрос, но я недавно наткнулся на него, переписывая свой сайт как приложение 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

Ответ 5

Это не работает, потому что конкретные события не запускаются, на которые привязан аффикс. В приложении с одной страницей, так как в вашем случае страница загружается только один раз, поэтому всякая логика, связанная с загрузкой страницы и подобными событиями, терпит неудачу. Все будет хорошо работать, если вы перезагрузите страницу.

Решение состоит в использовании угловатого пути. В одном из комментариев предлагается использовать angular -страницу, поскольку она имеет директиву аффикса для той же цели.

Я столкнулся с подобной ситуацией и в итоге использовал MacGyver Он работает очень хорошо и прост в использовании.