2016-01-12 4 views
1

Будучи довольно новым для Углового Я в настоящее время создаю приложение с использованием углового и Angular Material, пытаясь написать мою первую директиву. Я столкнулся с некоторыми проблемами.Угловая директива не работает после изменения маршрута

Что я хочу сделать: У вас есть карта на странице с панелью инструментов наверху. Как только панель инструментов прокручивается в верхней части экрана, она будет «прилипать». Чтобы добиться такого поведения, я написал простую директиву.

app.directive("sticky", function() { 

return { 
    restrict: 'A', 
    link: function(scope, element, attrs) { 

     //"content" is the container in which my app scrolls. 
     var content = document.getElementById('content'); 
     angular.element(content).bind("scroll", function() { 

     var cardOffset = element[0].parentElement.offsetTop; 
     var scrolled = content.scrollTop; 
     var cardHeight = element[0].parentElement.clientHeight; 
     var bottomOffset = cardOffset + cardHeight; 

     //Check if we are currently scrolling through this element. 
     if (scrolled >= cardOffset && scrolled <= bottomOffset) { 
      element[0].style.top = (scrolled - cardOffset) + 'px'; 
      scope.shadow = true; 
     } else { 
      scope.shadow = false; 
     } 
     if (scrolled <= cardOffset) { 
      element[0].style.top = '0px'; 
     } 

     }); 
    } 
} 

}); 

Адрес plunker of that in action. Как вы можете заметить, plunker работает так же, как я описал выше.

Однако, когда я помещаю это в свое приложение, я получаю следующее странное поведение: при посещении представления, содержащего липкий элемент, указанный элемент не имеет липкого поведения. Мое первоначальное предположение было чем-то неправильным с $ routeProvider, но, как показывает плункер, оно работает с этим.

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

+0

Скачивали код, как это. Приличное поведение работает как ожидается в Safari и Firefox. Какой браузер вы используете? – oKonyk

+0

Извините, если я не был достаточно ясен в своем посте. Хотя он работает так, как предполагалось, в плунтере, я получаю проблемы, когда фактически использую его в своем приложении. Я просто застрял без идей, что посмотреть. –

+0

У меня есть эта часть, я тестировал ее непосредственно в браузере (без использования plunker, я загрузил необработанные файлы) – oKonyk

ответ

2

Эти проблемы обычно возникают, поскольку DOM не полностью загружен до запуска JS. Если вы добавляете $ timeout вокруг своего элемента, то он работает без проблем.

Смотрите отредактированный plunker: https://plnkr.co/edit/xyjNRuEpRQ09KFHFcHjx?p=preview

app.directive("sticky", ['$timeout', function($timeout) { 

    return { 
    restrict: 'A', 
    link: function(scope, element, attrs) { 
     $timeout(function() { 
     var content = document.getElementById('content'); 
     angular.element(content).bind("scroll", function() { 

      var cardOffset = element[0].parentElement.offsetTop; 
      var scrolled = content.scrollTop; 
      console.log(scrolled); 
      var cardHeight = element[0].parentElement.clientHeight; 
      var bottomOffset = cardOffset + cardHeight; 

      //Check if we are currently scrolling through this element. 
      if (scrolled >= cardOffset && scrolled <= bottomOffset) { 
      element[0].style.top = (scrolled - cardOffset) + 'px'; 
      scope.shadow = true; 
      } else { 
      scope.shadow = false; 
      } 
      if (scrolled <= cardOffset) { 
      element[0].style.top = '0px'; 
      } 

     }); 
     }, 0); 
    } 
    } 
}]); 
+0

Ничего себе, спасибо, работает как шарм, и я получаю рассуждения позади этого. Есть ли еще более угловатый способ сделать это? как событие, которое я мог слушать? –

+0

Похоже, что тайм-аут - это на самом деле путь, согласно http://stackoverflow.com/questions/24411549/avoiding-timeouts-in-angular-applications. Также попробовали «$ locationChangeSuccess» и «$ routeChangeSuccess» без успеха. Таким образом, тайм-аут кажется таким. –

Смежные вопросы