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 Он работает очень хорошо и прост в использовании.