2015-10-15 2 views
3

Я ищу, чтобы пользователь щелкнул ссылку на странице, это вызовет stateChange и приведет их к новому состоянию. то, что я хочу достичь, - это когда состояние закончено, загрузив его, затем прокручивается до привязки на странице, указанной ссылкой на предыдущей странице.AngularJS: Автоматическая прокрутка до точки привязки после изменения состояния

делать это, я использую комбинацию пропускания $ stateParam через щ-sref так:

<a ui-sref="stateParent.stateChild({id: 'practiceParam'})">goToPage</a> 

тогда, когда страница будет достигнуто есть DIV сидит на нем с директивой прикрепленного что активируется в $ viewContentLoaded, поэтому DOM отображается, и я могу найти идентификатор. HTML-ДИВ выглядит следующим образом:

<div scroll-after-load ></div> 

и моя директива прокрутки выглядит следующим образом:

angular.module('app').directive('scrollAfterLoad', function() { 
    return { 
    restrict: 'A', 
    link: function(scope, $elm, attrs, $stateParams) { 
     scope.$on('$viewContentLoaded', function() { 
      console.log('scrollAfterLoad Directive Loaded, $stateParams are: ', $stateParams); 
      var idToScroll = attrs.href; 
      var $target; 
      if (idToScroll) { 
       $target = $(idToScroll); 
       // the -50 accounts for the top navbar which is fixed on the page and removed from pageflow 
       $("html,body").animate({scrollTop: $target.offset().top - 50}, "slow"); 
      } 
     }); 
    } 
    }; 
}); 

я не беспокоил с установкой HREF на DIV пока я не могу получить доступ к переданному параметру, я Я обращаюсь к нему неправильно? Я также попытался использовать более стандартный state.go() для передачи stateParam, но мой результат по-прежнему равен нулю.

Как только я могу передать государственный шаблон, Идея - это просто добавить href к параметрам, которые вводятся в div на вновь загруженной странице, и автопрокрутить в другой div на этой странице с идентификатором, который соответствует моему переданному параметру.

Кроме того, обратите внимание, что на моем экране ii-auto у меня есть autoscroll для true, поэтому страницы автоматически загружаются вверху, мне нравится это поведение, и именно по этой причине мне нужно состояние для полной загрузки до активации scoll ,

+0

интересное решение, но id скорее избегает большей зависимости в моем проекте и пишет для него простую директиву. – Eolis

ответ

2

Ваша проблема заключается в том, что вы пытаетесь привнести $stateParams службу в функцию связи. Тем не менее, правильное место для такого типа впрыскивания происходит на фабричном методе, это означает определение директивы. Заводский метод регистрируется модулем - как в вашем случае с директивой scrollAfterLoad. Для получения дополнительной информации проверьте AngularJS Dependency Injection.

Итак, вернемся к вашему вопросу: если вы фактически вводите $stateParams в свой заводский метод своей директивы, значит, в верхней части вы сможете легко получить доступ к параметрам. Ваша директива может выглядеть следующим образом:

angular.module('app').directive('scrollAfterLoad', ['$stateParams', function($stateParams) { 
    return { 
    restrict: 'A', 
    link: function(scope, $elm, attrs) { 
     scope.$on('$viewContentLoaded', function() { 
      console.log('scrollAfterLoad Directive Loaded, $stateParams are: ', $stateParams); 
      var idToScroll = attrs.href; 
      var $target; 
      if (idToScroll) { 
       $target = $(idToScroll); 
       // the -50 accounts for the top navbar which is fixed on the page and removed from pageflow 
       $("html,body").animate({scrollTop: $target.offset().top - 50}, "slow"); 
      } 
     }); 
    } 
    }; 
}]); 

Обратите внимание, что я удалил $stateParams из вашей функции связи и поместить его в верхней части. Таким образом, услуга будет уже доступна в функции ссылок - фактически в рамках всей директивы.

Я воспроизвел ваш сценарий в этом Plunker.

+0

Я вижу, это имеет смысл, и у меня есть параметры, работающие в моем проекте. Большое спасибо за помощь! надеялся, что я просто помещаю что-то не в то место или неправильно обращаюсь к параметрам. – Eolis

2

С angular-scroll вы могли бы сделать это следующим образом:

Пройдите свой scroll target id как состояние параметра для ребенка состояния контроллера, а затем перейдите к элементу с scrollToAnimated(element).

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

Возможно, вам потребуется перезапустить прокрутку, если вы находитесь в дочернем состоянии, и снова нажмите ссылку на изменение состояния. Вот почему я добавил метод checkState, который перезагружает текущее состояние, если мы находимся в дочернем состоянии, чтобы повторить прокрутку.

Пожалуйста, взгляните на демо внизу или в этом fiddle.

Я думаю, что ваша директива не работает, потому что вы не передаете атрибут href вашей директиве.

Вы можете исправить это, передав href="targetId" в вашу директиву, где targetId добавлен с $scope.targetId = $stateParams.id в ваш дочерний контроллер. Или вы можете получить доступ к targetId$scope непосредственно, если вы не используете изолированную область.

В любом случае я бы сделал это, как будто я сделал это в демо или с фабрикой внутри разрешения.

angular.module('demoApp', ['ui.router', 'duScroll']) 
 
\t .controller('MainControlller', MainController) 
 
\t .config(Config); 
 

 
function MainController($scope, $state) { 
 
\t $scope.checkState = function() { 
 
    \t //console.log($state.current); 
 
     if($state.current.name == 'parent.child') { 
 
      //console.log('parent.child state'); 
 
     \t // reload to retrigger scrolling again 
 
      $state.reload(); 
 
     } 
 
    }; 
 
} 
 

 
function Config($urlRouterProvider, $stateProvider) { 
 
\t $urlRouterProvider.otherwise('/'); 
 
    
 
    $stateProvider 
 
    \t .state('parent', { 
 
     \t url: '/', 
 
     \t templateUrl: 'home.html' 
 
    }) 
 
    \t .state('parent.child', { 
 
    \t url: 'child/:id', 
 
     templateUrl: 'child.html', 
 
     controller: function($scope, $stateParams, $document) { 
 
     \t var scrollElement = angular 
 
       .element(document.getElementById($stateParams.id)); 
 
      console.log(scrollElement); 
 
      $document.scrollToElementAnimated(scrollElement); 
 
     } 
 
    }); 
 
       
 
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-scroll/0.7.3/angular-scroll.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.15/angular-ui-router.js"></script> 
 
<div ng-app="demoApp" ng-controller="MainController"> 
 
    <script type="text/ng-template" id="home.html"> 
 
     <a ui-sref="parent.child({id: 'practiceParam'})" ng-click="checkState()">go to practice</a> 
 
     <div ui-view=""></div> 
 
    </script> 
 
    <script type="text/ng-template" id="child.html"> 
 
     <!--<a href="#practiceParam" du-smooth-scroll="">scroll to practice</a> 
 
     --><p> 
 
      Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. 
 
     </p><p> 
 
Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. 
 
     </p><p> 
 
Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.</p> 
 
<p> 
 
Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. 
 
     </p> 
 
     <p> 
 
      Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. 
 
     </p> 
 
     <h1 id="practiceParam">practice</h1> 
 
     <p> 
 
Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. 
 
     </p><p> 
 
Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.</p> 
 
<p> 
 
Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. 
 
     </p> 
 
     <a ui-sref="parent">back</a> 
 
    </script> 
 
    
 
    <div ui-view=""></div> 
 
</div>

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