Remove / cancel animations in ui router when navigating back and forth - javascript

I'm using AngularJS ui router and I have about 3 pages in total. The problem I am facing is that on the home page (first page) I have an intro animation which lasts about 10 seconds in total. The intro animation is attached to the directive.
Now once I land on that page, the intro starts and everything is fine until I navigate to another page - it seems that the intro keeps playing as if the DOM and in particular - the directive was not removed properly.
Is there a way to remove / clear DOM before navigating to another page?
The code is massive to post here and I was wondering if there is a quick fix for this? If not, I will try to post it on jsfiddle.

Mabe something like this will help
.run(function($rootScope, $route, $location) {
$rootScope.$on("$stateChangeStart", function (ev, to, toParams, from, fromParams) { {
//to.name is new state name
//from.name is old state name
TweenMax.killTweensOf($("#yourId"));
});
});

Related

ui-router: Reset $state without using $state.go()

First off, I think the overall issue here is that AngularJS still doesn't have a sensible, best practice way of "restarting" the app and all its components. So far, the best practice seems to be setting the path to a "default" view, and then reloading the window. We do this in our /logout state, as seen here:
$stateProvider.state('logout', {
onEnter: function($state, $window, store) {
//Remove any session variables
store.remove('varA');
store.remove('varB');
//"Logout" the user
$state.go('login');
$window.location.reload();
}
})
However, this is a bad user experience. The user can actually see the view change and the components on the page shift before the window reloads. It just seems very buggy overall.
Originally, we did not include $state.go('login'), and did not get the weird experience of seeing the view change before logout. However, when we started using $state handlers like $rootScope.$on('$stateChangeStart', function (event, toState, toParams), we noticed that toState was not being reset after the window reload. So $stateChangeStart would trigger after the reload, and toState would still be set to whatever view the user was on before calling /logout. This isn't a true app reset!
Possible Solution: I think all of this can be solved if there was a way to "reset $state" without using the $state.go() method...something that happens behind the scenes instead.
Simple code change fixed it for me
//"Logout" the user
$state.go('login', null, {notify: false}).then(function() {
$window.location.reload();
});
Source: https://github.com/angular-ui/ui-router/issues/2486#issuecomment-180872463

AngularJS with ui.router: reload page when clicking the same state link

I just got a request from our QA team, which I think sounds ridiculous. Here it goes: suppose you are already on the 'about' state/page in the angular-based app, and when you click on the 'about' state url again from the top menu, you want the 'about' page to reload. The about page does not fetch data from anywhere, by the way, a reload is simply equivalent to a blink.
For the state config in my angular app is like this:
.state('about', {
url: '/about',
templateUrl: '/path/to/about.html',
controller: 'aboutCtrl as aboutView'
});
And in the top menus, we have a link pointing to this state:
<a ui-sref="about">About</a>
I have tried many things to get this to work: clicking the link triggers the reload of the same state.
Things like $state.go('about', {}, {reload: true}); or $state.transitionTo('about', {}, {reload: true}); don't work, because the links are static.
One last resort I am currently trying is to manipulate the reload thing in the run phase of Angular by listening to '$stateChangeSuccess' event, but I don't think it will work, because there's no state change at all if you click on the 'about' link while you are right on that state.
Is there any ways to work around this? Thanks
There is an option attribute called ui-sref-opts that comes with the UI Router. I faced the same problem and it solved it.
Eg: <a ui-sref="home" ui-sref-opts="{reload: true}">Home</a>
Docs URL : UI Router DOcs
You're right, I can't get any state change events to fire either once already in that state. Until, and if that functionality becomes available to use through that api someday, here's a semi-hacky solution for this. We can just leverage ng-click and use some silly logic to appease QA (in your case). Also, I don't know your controller implementation, so I placed my suggestion on $rootScope in .run in this example for simplicity and visibility, but integrate accordingly if you choose to do so. Observe the following example...
<a ui-sref="about" ng-click="sillyQA()">About</a>
.run(['$rootScope', '$state', function($rootScope, $state) {
$rootScope.sillyQA = function() {
if($state.current.name === 'about') {
$state.go('about', {}, { reload: true });
}
}
// -- just to see our about => about state 'change'
$rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams){
console.log('toState: ' + toState.name );
console.log('fromState: ' + (fromState.name || 'Just got there! click again!'));
})
}]);
JSFiddle Link - demo

Angular UI Router: Setting autoscroll on header view does not scroll to top

TL;DR: With Angular UI Router, is it possible to autoscroll to a view of the same state that the template displaying it belongs to?
The Setup
I have an Angular 1.4.1 app, using UI Router 0.2.15 and Angular Material 0.10.0.
Example Plunk
There is a parent state called website and three child states: home, foo and bar.
The parent state has a wrapper view, which is displayed via the <ui-view> tag in index.html. It also has two other views, header#website and footer#website, which it displays via the wrapper view template.
Each of the three child states has a main view, which is displayed via the parent state's wrapper view template.
What I Expect
In the parent state's wrapper view template, when I set autoscroll="true" on the ui-view tag for the header#website view, I expect that the page will scroll to the top whenever the state changes. See the accepted answer of this SO question.
What Is Happening
When any of the ui-sref links in the footer is clicked, the page does not scroll to the top.
What I've Tried
If I put autoscroll="true" on the ui-view tag for the main view, it works as expected. This is not what I want, however, because the header is hidden from view even when you navigate to a state from the address bar.
What I Suspect
I think the problem has to do with the fact that header#website is a view that belongs to the website state, and that autoscroll only works for views that normally are displayed on the current template. In other words, normally the header view would be displayed via index.html, not wrapper.html.
The Question
Is my suspicion above correct? Do I need to refactor, or is there a way to make this work as is?
Thanks in advance!
Though I don't advocate DOM manipulation outside of a directive, a quick and dirty solution would be to add a scrollTo method in a .run block of your top level module definition, for ex:
.run(function ($window, $rootScope) {
$rootScope.$on('$viewContentLoaded', function () {
var interval = setInterval(function () {
if (document.readyState == "complete") {
window.scrollTo(0, 0);
clearInterval(interval);
}
}, 1);
});
})
http://plnkr.co/edit/qPqy69o7F9aTjNbUTMGY?p=preview
(borrowed from here https://stackoverflow.com/a/22166553/1516309)
I tried using the $anchorScroll() method of ui-router, but since your links are at the bottom of the page, thats where the page scrolls to, so you dont actually notice it doing anything.

Using AngularJS $anchorScroll to scroll to another page's anchor tag

From my AngularJS Home Page I need to scroll to an anchor tag in another page. Both these pages are coming as partial html's into the ng-view component, based on the url. On starting the server, the home page is loaded and from there in need to go to the faq page. I used the normal href with #, but that didn't point to the correct div in the target page. Here is what I tried with $anchorScroll
Here is the controller method
$scope.scrollToFaq = function(id) {
$location.path("/faq")
$location.hash(id);
$anchorScroll();
}
Here is how I use it in the home.html
<a ng-click="scrollToFaq('HERE')" href="" class="link">Here</a>
But this is not working properly. If I load the faq page directly and then come back and click the anchor link from the home page, it works. Is it possible to do this with `$anchorScroll
Try to use Angular's $timeout service.
$scope.scrollToFaq = function(id) {
$location.path("/faq");
$timeout(function(){
$location.hash(id);
$anchorScroll();
}, delay);
here delay would be the time you would like to wait until the anchor scroll happens. I have read about 300ms / 400 ms working for people. When I had this issue, I just had to call the $anchorscroll inside the $timeout. So use what's best for you case.
Note: I am on the lookout for a solution without the use of $timeout. Will update when I find one.
Sounds like a history related issue. If the div has already been loaded once it is found immediatly. This solution worked for me in the past. Maybe an idea to wait for the page to load.
$scope.scrollToFaq = function(id) {
$location.path("/faq");
$(window).on("load", function(){
$location.hash(id);
$anchorScroll();
});
};
Had the same problem. But fixed it :)
Idea is to change to the URL, wait a halfsecond and than jump to the anchor.
HTML:
Links
Controller:
angular.module('exampleApp').controller('NavbarCtrl', function ($scope, $location, $timeout, $anchorScroll) {
$scope.goToAnchor = function(path, anchor){
$location.path('/');
$timeout(function() {
$anchorScroll(anchor);
}, 500);
};
});

$state.go doesn’t redirect to given path

i've got a view that's outside of my tabs, now when i try to redirect from that view to a tab i get redirected to the wrong tab. i've made a codepen to show you what i mean since i don't really know how to explain it well see the logs i create in the console
.controller('MyCtrl', function($scope, $state, $rootScope, $ionicPlatform) {
$rootScope.$on('$stateChangeStart',function(event, toState, toParams, fromState, fromParams){
// do something
$scope.from = fromState;
console.log(fromState);
})
$scope.goBack = function(){
console.log($scope.from.name);
$state.go($scope.from.name);
}
})
Codepen
You should apply the other answers but you have another problem.
The other problem is that, when you click on back button the state is changing to tab.volgend (which is right) but after this is going to tab.alert state... so I'm trying to figure out why is this second redirect happening.
Extract from console.log when clicking back button:
My first candidate is:
$urlRouterProvider.otherwise('/tab/alerts');
You shouldn't use ui-route with standard routing, so you should comment this line an add the next in your controller:
console.log('going to default state');
$state.go('tab.alerts');
EDIT
The second transition is made by the ionic framework, I have put a breakpoint and check the callstack, check this captures:
1- first call when back is clicked:
2- The ionic framework detects a change in the url and.. fires the second transition:
I'm going to read more this framework to see if I understand why is this happening... I keep you updated.
You should pass the name of the state to $state.go(), not the state object.
So $state.go($scope.from.name) should solve this for you.
why not simply use
$state.go('stateName', {//for stateParams}, { reload: true });
This happened with me too. Try transitionTo method, instead of go
$state.transitionTo($scope.from.name);
This worked out in my case.
More details can be found here
Edit : I forked your original codepen and it worked there too.. Forked Codepen here

Categories

Resources