I'm making a mobile app using Cordova and AngularJS. Currently I have installed ui-router for routing but I'm open to any other alternative for routing.
My desire: I want to cache certain views bound with parameters. In other words I want to cache paths (or pages).
Example situation: let's say that we see some dashboard page, click on some book cover which redirects to the path book/2
. This path is being loaded for the first time into app. Router redirects from HomeController
to BooksController
(whatever the name). Now the BooksController
loads data for given $stateParams
(book id = 2) and creates view filled with info about chosen book.
What I want in this situation:
- I go back to the dashboard page - it is already loaded (cached?)
- I choose book #2 again
- Controller or router notices that data about this book is already loaded
- The view isn't being recreated, instead it's being fetched from cache
Actually, it would be best to cache everything what I visit based on path. Preloading would be cool too.
Reason: performance. When I open some list of books then I want it to show fast. When view is being created every time, then animation of page change looks awful (it's not smooth).
Any help would be appreciated.
EDIT:
First of all, since I believe it's a common problem for many mobile HTML app programmers, I'd like to precise some information:
- I'm not looking for hacks but a clear solution if possible.
- Data in the views uses AngularJS, so YES, there are things like
ng-bind
,ng-repeat
and so on. - Caching is needed for both data and DOM elements. As far as I know, browser's layout operation is not as expensive as recreating whole DOM tree. And repaint is not what we can omit.
- Having separate controllers is a natural thing. Since I could leave without it I cannot imagine how it would work anyway.
I've got some semi-solutions but I'm gonna be strict about my desire.
Solution 1.
Put all views into one file (I may do it using gulp builder) and use ng-show
. That's the simplest solution and I don't believe that anyone knowing AngularJS would not think about it.
A nice trick (from @DmitriZaitsev) is to create a helper function to show/hide element based on current location path.
Advantages:
- It's easy.
- KIND OF preload feature.
Disadvantages:
- all views have to be in a single file. Don't ask why it's not convenient.
- Since it's all about mobile devices, sometimes I'd like to "clear" memory. The only way I can think of is to remove those children from DOM. Dirty but ok.
- I cannot easily cache /book/2 and /book/3 at the same time. I would have to dynamically create DOM children on top of some templates for each view bound with parameters.
Solution 2.
Use Sticky States AND Future States from ui-router-extras which is awesome.
Advantages:
- Separated views.
- Very clear usage, very simple since it's just a plugin for
ui-router
. - Can create dynamic substates. So it would be possible to cache
book1
,book2
but I'm not sure aboutbook/1
andbook/2
Disadvantages:
- Again, I'm not sure but I didn't found an example with caching a pair/tuple
(view, parameters)
. Other than that it looks cool.
ng-repeat
and so on. So I suppose it's not just about using$templateCache
– Scrivnerorder/1
first state,order/2
other state and so on, but dynamically. I mean, I don't know what number of orders do I have. Do you think that's possible with Sticky States? – Scrivnerng-show
exactly the way I described. Plus the overhead of loading extra library with no clear advantages. Sounds like a complicated solution for what can be done simple: christopherthielen.github.io/ui-router-extras/example/sticky/… – Talbert