I am new to Vue. I am using Vue-router and I have some animations and videos on my index page.
I would like to prevent the index page from refreshing if I navigate away to the about page for example, so that the user, when they click back to the index page won't have to start the videos and animations again.
Which lifecycle hooks would I need to make use of and is their a simple way to implement it?
After #Yom S pointed me in the direction I did some research and discovered that wrapping the router-view HTML elements in keep-alive tags we can achieve the outcome I desired. By explicitly naming the components one can make use of "includes" "excludes" keywords within the keep-alive element to include or exclude certain router views from re rendering
here is a link to an informative conversation on the vuejs forum regarding this very problem
https://forum.vuejs.org/t/conditional-keep-alive-with-vue-router-not-working/4319
Related
I'm not quite sure what would be the best way to handle a particular scenario.
With 2 components rendered on the same page, links in one component will control the data displayed in the other component.
I am using the Flux pattern, so I typically would propagate this through, but my goals are:
reflect the change in the url /path
no actually navigate away or cause transition
One of my constraints is: the component with the links is a 3rd-party library that renders the links. But I have control ove the URL's.
I am not sure if it is possible to both:
use the Flux pattern for this scenario
And (with react-router) reflect the selection in the URL
e.g.
/some/url/1
[comp1] -> link clicked -> [comp2] -> displayed data changed
path becomes -> /some/url/2
Any suggestions?
So I'm trying to make a single page web application that makes use of AngularJS's routing mechanism and so far it's working brilliantly, but I noticed that when the route changes, the view seems to be completely deleted and replaced with the new one.
Is there any way to keep the old view around so that it doesn't have to re-download all of its data when the user goes back to it? Also it would be nice so that their scroll position would be retained.
Any ideas?
Using UI-Router I solved this problem with the angular ui router extras. Here you will find the sticky states that will perhaps do what you want. Quote from the website:
Sticky States allows a tree of states to be long-lived, running
concurrently alongside one or more other state trees. This is also
sometimes referred to as Parallel States. The basis for this
functionality is to implement a "tabs" use case. Using UI-Router
Extras Sticky States, a single page angular app can implement
independent tab state trees, which operate in parallel to each other.
Does that help?
I need to use two states in parallel, one for my page and an other for a modal with several sub states.
Right now calling the modal state will wipe out my page since the page state changed.
Create a child state child of my page wouldn't be a solution since the modal will be used on several pages.
Example:
$stateProvider
.state('user', {}) // page
.state('bookshelf', {}) // page
.state('books', {}) // modal
.state('books.read', {}) // sub state of modal
So if I'm on user and open my modal then the state would change to books, my modal would then have the content but the page content will be wiped out.
How do I fix it?
I believe the way you're looking to do this is not possible with UI.Router currently. What you're describing is a modal component (which would ideally be written as a directive), which tracks it's state independently from the main state.
The way to think about it, is that UI.Router works by creating a state tree. At any given time you can only be looking at one branch of the tree. You can go deeper down a branch (ie: book, book.open, book.open.checked), but you can't be in two places at once.
Another issue with the problem above is how do you serialize the state of the two different trees into one url? It's not to say it can't be done, it's just a hard problem to solve.
Checkout these issues:
https://github.com/angular-ui/ui-router/issues/119
https://github.com/angular-ui/ui-router/issues/384
https://github.com/angular-ui/ui-router/issues/475
Also checkout these repos, they might be further along the lines of solving the problem.
https://github.com/afterglowtech/angular-detour
https://github.com/stu-salsbury/angular-couch-potato
As far as solving your immediate problem, I think the 'easiest' way would be to ditch controlling the state of the modal inside your state config.
Instead, I would add some sort of root or abstract state, and then track whether the modal is open there. Then, you can communicate between controllers using events as shown here. Note: There are performance implications with listening to $rootScope, so be sure to research those. However (someone feel free to correct me), the implementation here doesn't have those problems, because the AppCtrl is never destroyed.
Jan 15, 2015 Edit
Turns out this is a pretty popular use case, and one of the core contributors to UI Router maintains a plugin/addition called UI Router Extras
It also includes utilities for lazy loading, called "Future States" which are very helpful.
That being said, one feature I'm hoping to get time to work on is maintaining all state within the URL (or perhaps, local storage) and allowing for reusable state "components". The latter is in the UI Router roadmap as well.
In a single page application, is there a way of switching back and forth to an AngularJS route and to display it back in the same state as it was shown before?
Usually this would be implemented by binding data in a parent scope. While this is easy to set up for lightweight view, it can be cumbersome when doing it for views holding lots of graphical elements.
Here is an example, where having the previous route state remembered could enhance user experience: on the following page, imagine that
you stand on Item 1 and select Tab 2
then move to Item 2
finally switch back to Item 1: Tab 2 is not selected anymore :-(
http://angular-route-segment.com/src/example/#/section1/1
It seems the views are destroyed/constructed when switching back and forth between routes.
A solution would be about storing the state of the user interface in a parent scope but it has the following pitfalls:
creating an object storing all the little details of the user interface
creating complex logic about -saving and- resetting the UI in the same state as before
storing UI state in a data model does not sound that MVC-ish
Using show/hide of div storing the views saves the state but then no route is used and the switching business must be implemented by hand. I like using routes because 1. of the browser history navigation (hash in the url) and 2. it is easy to set up.
Having the UI state not remembered is like having Chrome to reload pages when switching back and forth between tabs: not very user friendly.
Is there an Angular-way?
Your $routeSegment approach is very interesting. The $routeSegment service could plug into the $routeChangeStart event in order to
Somehow keep a "sub path history" on all paths seen so far, maybe only for those explicitly configured to keep their UI state. In your example for the path "/section1/1" the stored sub path would be "/Y" if tab 2 was selected. Things get interesting, as also dynamic paths with $routeParams might need to be covered.
Use this history for redirecting by using $location.path in the event handler. So a $routeChangeStart event with next.originalPath being "/section1/1" might be redirected to "/section/1/Y"
I've run into this on a few apps now, so I wonder if I'm doing something wrong with Backbone history. Here's the situation...
I have two pages, let's say:
index.html
app.html
The index page is just a normal, flat HTML page with a link to app.html. On the App page, Backbone.history.start() is called to fire up hash state management, which is used to toggle between two views on the App page, say:
app.html#search
app.html#results
So, navigating back and forth between the #search and #results pages works great. No problems there. The issue occurs when you try to use the back button to step all the way back to index.html. The path back to the index page involves a stop at app.html (no hash state), at which the Backbone router dutifully fills in missing hash state, putting you back at app.html#search. Again, clicking the back button will go to app.html, which fills in the missing hash state again... basically, you're now stuck in a loop and can't go back from the page. This same behavior occurs when using push state.
This seems like a potentially common problem with apps that automatically fire up their own routing system on top of a default page URL. Does anyone know of a good way to avoid this?
The problem is that app.html isn't doing anything on it's own; and so, may somehow break the app if navigated.
In this case, what you could do is instead of redirecting the root route to another, just use it as the default page:
routes: {
"": "search",
"results": "results"
}