$anchorScroll and $location only work after second try - angularjs

I am trying to use $anchorScroll and $location.hash() to scroll to a div. I have a bottom on the top of the page. When I click the bottom, I want the page to scroll down to the bottom of the page where I have a <div id="target">.
For some reason, the first time I click the button, my page doesn't scroll. If a click a second time, the page does scroll. And afterwards the scrolling works fine. This weird behavior can be reproduced if I refresh my page.
I have this code in my controller:
$scope.scrolldown = function() {
$location.hash('target');
$anchorScroll();
}
I know that the $location.hash('target') line is supposed to append a hash value to the end of my URL.
Here's the URL when my page first got loaded:
http://run.plnkr.co/iqvdGjdeCP4idP4D/
After I clicked my button for the 1st time, it becomes:
http://run.plnkr.co/iqvdGjdeCP4idP4D/#/target
which was not right (and the page was not scrolling properly).
After I clicked my button for the 2nd time, it becomes:
http://run.plnkr.co/iqvdGjdeCP4idP4D/#/target#target
From this point on the page started to scroll properly, but the URL still looks very strange to me -- why would I want two hash values?
I want to know why the button only works after second click and how to correct it.
Update
I added routing to my code and the scroll is working fine now.
Here's my plunker demo with routing.

Take a look at this question, which contains a possible solution for you:
Supress reloading of ui-router based view on query parameter change
It works the second time you click the button because the hash doesn't change (and so the route doesn't reload). Notice the page flickering when you click it the first time? That's an indicator that the whole DOM has been re-rendered.

Related

Angular Retain Proper Scroll Position when Transitioning Routes or Refreshing

I'm using ui-router.
A similar question has been asked on this a Number of times... But the solutions seem to be all over the place and either the question doesn't address a simple idea or the answer doesn't, either.
Here's my simple ui-view setup:
A master view has the navbar and footer
Children of the master view/route that can be activated include the Homepage, About Us page and Learn More page
Pretty simple...
By default, if the homepage is activated, and scrolled down 500px, and I click on a route to the "About Us" page, that page will be scrolled down 500px. Obviously this is not desired.
So... Everyone's solution is some variation of setting document.scrollTop(0) on every state change success. This is atrocious.
While it fixes the issue at hand, it clobbers the browser back button behavior. Here are some problems:
When a refresh is called, the standard browser behavior of refreshing to the current location is ruined
When the back button is clicked, the homepage would then scroll all the way to the top
If the back and forward button were clicked, I wouldn't retain the correct spot on the next page, either
This whole document.scrollTop(0) or any variation of it, really doesn't seem to be viable and I've yet to see a clear solution to this.

Why is the controller for a view loaded twice?

Please check this plunk for the issue I am explaining below.
When you run the plunk you will observe that there are certain tabs. The first tab Home belongs to home state. The remaining tabs belong to category state each tab identified by a category ID.
When I am currently on Home tab and I click on some other tab, the CategoriesController is invoked just once as expected. But when I click on some other tab from there the CategoriesController is invoked multiple times, once for the previous tab and twice for the newly selected tab. Please run the plunker and observer the browser console to better understand it.
I do not know why the controller is invoked for the previous tab also. Any help would be appreciated.
Not sure about the reason of invoking controllers multiple times. I'm trying to figure out the problem but till then you can do the following:
Remove controller: "CategoriesController" from the state configuration
Add ng-controller="CategoriesController" to the ui-view="categories" element
This will work for now since only that view -> controller will be invoked which is active.
Edit:
Got the problem, you have the ui-view="categories" in each tab so n number of ui-view are being rendered for n number of your tabs.
Now what is actually happening, to provide the slide animation, Angular material is keeping the left and right tab available in the DOM as well.
So when you are clicking from Home (i.e. first tab) to another tab, it's working fine. But when you are going from any other tab (other than 1st tab), it's respective left & right tab are coming into action as well since the sliding effect needs to be performed.
U are changing seletedTab value in your CategoriesController and $stateChangeStart $watcher.but at the same time u are using ui-view with ng-if which need the seletedTab as a parameter.
Say currently u are on tab 0, and switching to tab 1. And Things happens like this:
First of all, ur state change start.In the $stateChangeStart watcher, the selectedTab is set to 1.
The ui-view in tab 0 is removed from DOM.
The ui-view in tab 1 is added to DOM, but currently the $stateParams.catID is still 0.In this way, it initiated the CategoriesController with $stateParams.catID = 0. And at the same time, it set the seletedTab to 0. This is the first invoke for previous Controller
The ui-view in tab 1 is removed from DOM and ui-view in tab 0 is added to DOM.
Then ur $state changed successfully. The ui-view in tab 0 inited the CategoriesController with $stateParams.catID = 1 and set the seletedTab to 1.This is the first invoke for next Controller
OK now the ui-view in tab 0 is removed and the ui-view in tab 1 is added to DOM again and finally inited the CategoriesController with $stateParams.catID = 1. Everything looks OK though. This is the second invoke for next Controller
Hope i made it clear.

Go back to N'th "page" of a page in Angular

There is a page with thumbnails. At the bottom there is have a "Show more" button that loads more thumbnails. A user can click on a thumbnail and re-direct the application into details. When the user clicks browser's "back" I would like him to land in the same position as before. How to achieve this without complex routing?
You can achieve something like this using angular-bootstrap-lightbox and the ui-bootstrap pagination. Both are Angular and use common resources
EDIT:
What you're looking for is something along the lines of scroll-sneak, you want to save the scroll position when you redirect to another page and load the last position when you redirect back.
since I could not find any angular directive to do so, you can either
get one and wrap it around a directive, most of them use jQuery
you can make your own.
for example, you can use js to define a queue array and store it in localStorage/sessionStorage, when you redirect "push" the current page location to the queue, when you redirect back, "pop" that last stored position.
Maintain Scroll Position of large HTML page when client returns

NGgrid not refreshing after update in modal window

User can update value for multiple rows in an nggrid using a modal window. After user confirms update and closes modal window, grid does not refresh. Navigating away from page and coming back indicates that the update took effect, but I want this to take effect right away, without having to use location.reload(). Any ideas?
If your modal is a directive I'm guessing (without having seen the code) that you need a $scope.$apply in the directive...

AngularJS refresh and stay at same scroll position

I'd like a page refresh to resume the page from the last scroll position before the refresh was pressed.
I'm using AngularJS and something peculiar is happening because when I refresh it first goes to the top of the page, then as soon as I scroll it will resume from the last scroll position before I hit refresh.
Very odd behavior, no?
How about providing a route like /app/:currentScrollTop
and then you can based on that parameter to scroll your view to the desired position.

Resources