Ionic/AngularJS - Keep UI state between views - angularjs

I've been using Ionic/AngularJS in several projects and I'm always struggling on the same issue.
I process some data with several kinds of displays (list, map) and when the user clicks on an element, it redirects him to a details page.
It should be good if the framework allows us to keep the UI state of the previous view, so when the user clicks on the back button on the details page, the previous page holds infinite-scrolling position or google map state.
As a workaround, my details page are always modals so when the user wants to go back, the modal closes and the background content state is kept. Nevertheless, this is not an ideal way of coding because the code is way harder to understand, and some problems happens concerning memory (imagine that the details page is linked to another details page, so you have modals opening infinitely...)
Is there a way to keep UI state of a page?
Just to clarify, I'm not talking about variables state (easy to store: $rootScope, localStorage, POST variables, cookies...).
TL;DR:
I have a google map, when I click on a marker, it's redirecting me on a details page, when I go back, I want to get the google map state back, how can I do it?

I think you can create a controller which will be used as a base controller for your other controllers. You can put some data in this base controller and inject it in your controllers responsible for google maps and its details

Related

Use Angular Ui-router without any views or templates

I've used UI router in the past in single page applications and found it prefect for loading new views and syncing them with the URL. However, I now have a normal multi-page ecommerce site which uses Angular a lot on various pages. Including te search results page.
I need to use ui-router only on this page to do ajax paging. Basically the content is already loaded onto the page and I have an ng-repeat for the results. It's a very simple set up.
What I want to do is change the state/url when the user hits the next/previous buttons and watch the stateParams to look for the new page number, then manually reload the new results and re-bind the ng-repeat to show the new results. Obviously I could load new search results without using ui-router at all but I want the back button to work so that you can go back through the pages.
Now, as far as I can see none of this requires any ui-view tags, or templates or controllers. I simply want to update the URL when a button is clicked and watch for changes. Is this possible with UI-router and if it is then what routes (if any) do I put into $stateProvider config?
Any help would be greatly appreciated.

Ionic framework maintain view state

I have a tab in my Ionic project which consists of a map. On that map, the user can pan around and do things such as draw polygons, etc.
However, when the user moves to another tab and comes back, the map is completely reset and all his work is gone, because Angular seems to destroy the state. In addition, another request will have to be made to the map tile server because of this, which can be expensive (financially) for the company.
Is there a way to tell Angular not to reset the state when navigating from tab to tab? Or perhaps this project isn't a good fit for Angular based technologies?
I am not sure how the map is being created in your scenario, but have you tried nesting your states? http://angular-ui.github.io/ui-router/ has a great example of a nested state that shares data between them. You might also look into the $cacheFactory service: https://docs.angularjs.org/api/ng/service/$cacheFactory and use it to store and retrieve your map.

Angular UI Router - How to preserve views while switching views

I am I new to Angular and UI Router.
Plunk http://plnkr.co/edit/1wfyrGryfGG5RtXozPFY?p=preview
Setup I have three top level application nav buttons Home, Projects, Help. They load different views home.html, projects.html and help.html using the Angular UI Router ui-view directive. This works good.
The Projects.html view has a tab bar with each tab corresponding to a project: D1, D2 D3 etc., I show the corresponding project tab using url router attributes.
Every time I click the Projects button it is reloading the tab bar completely. I loswe the current tab and hopefully if any nested views inside it. Basically the page contents of Project.html, invoking the controller as well.
I read through the wiki documents and couldnt figure out how to implement my required functionality. I am sure I am missing something. Will it always reload the view?
Question: How to avoid reloading the projects view contents so that I can retain the selected tab and all the contents as-is before switching to Home. Because I would have a lot of nested views and models on each project.
I wanted similar functionality too, but ui-router doesn't yet support it. I forked ui-router to support "parallel states" and submitted it to the project for comment. The gist of the conversation is that ui-router will eventually support some form of parallel states but not yet. In the meantime, you can try my fork of 0.2.10 which provides the parallel states that you want.
Read the conversation here: https://github.com/angular-ui/ui-router/issues/894
View the sample parallel tabs plunk here: http://plnkr.co/edit/YhQyPV?p=preview
Here is the fork; build it with grunt: https://github.com/christopherthielen/ui-router
One option would be to implement a service that can be used to maintain the previous state. Services persist over controller changes, thus they can be used to maintain the previous page state and updated when the route changes. something similar to this would work.
app.factory('persitDataService', [function(currentStateData){
var stateService = {
state:{
//your object data set to passed in data
}
//other functions here
};
return stateService
});
then in the controllers just inject the service and assign to a scope value. When the route changes just reset the data in service to new state and inject into new controller
This should work for the previous page state. If you are wanting to save the states of all previous pages then this becomes a larger problem but should be accomplished in much the same way only with a more complicated service setup.
This could also be combined with local and session storage

How to preserve state of hidden views?

I'm an Angular newbie working on a Phonegap application with a few views: a map, a list, and search.
As the user interacts, each view accumulates some UI state: the map is dragged, the list gets a scroll position, a detail view is opened for a list item, a search is performed, etc. I'd like for the user to be able to navigate among views without losing this state.
When I put my views in partials in ng-view, and my nav links use href="#/path", or ng-click to trigger location.path(path), the controller is run and state is obliterated. Makes sense.
One option would be to ng-include all partials in index.html and ng-show based on the user's nav actions. However, I've found that this kind of complexity in the DOM will lead to poor Phonegap performance. It also feels that by eschewing routing, I'm losing one of the main benefits of using Angular.
Another thought: nav clicks cause traversal of browser history. Seems tricky to maintain the state of all views in parallel, however.
My question: is there a good pattern for this?
FWIW currently using Phonegap 3.0 and Angular 1.1.5. Thanks for your time.
If you want to preserve the state of the DOM in parallel views, there's an extension to ui-router called ui-router-extras. It has a a nice demo with state transitions and full DOM preservation when switching among tabs.
you can keep all the data that needs to persist between controller reloads in services
a simple example here
Preserve state with Angular UI-Router
a more complex example here that includes restoring state if the user leaves the page and then presses the back button
Maintain model of scope when changing between views in AngularJS

Backbone.js Marionette router and nested views

I'm diving into the whole "single page application" and Backbone.js (specifically Marionette) stuff. I'm working on a decently complicated application. I'm wondering how you set up the router to handle nested views so the "containing views" are also rendered. For instance let's say I have an Admin section and under that I have a Users section. Under Users I have tabs to "Add User" and "Search Users".
If I've selected "Add User", I imagine my URL has the fragment "#admin/users/add". That routes to a view that has the add user form. However, if you go directly to that URL I want to show that form again, but also the top navigation bar with "Admin" highlighted, the admin specific sidebar with my admin navigation and have "Users" button highlighted. I need the whole HTML page, not just the Add User ItemView.
How to do say when the page first loads (refresh or from a bookmark), to load the html structure and "parent views" as well? Thanks!
This is the way you need to think about the app's behavior:
the controller needs to create view instances and pass in the data they need (models, collections, etc.), and then display the views within the regions
the ONLY thing the router does is is match a URL to a controller action (i.e. "if this URL is entered in the address bar, the application should launch this controller action")
So bascially, this is your problem: you're missing a controller action (e.g. MyApp.AdminApp.Users.New.newUser() which will render the views you want, which you can then call from your router...)
One thing that helps (although not related to the problem you're currently facing), is to always call the navigate method with trigger: false (which is the default). This ensures that your app is behaving properly and that the router is limited to matching URLs to controller actions.
Regarding the menu (with highlighted current entry), I would make it a separate Marionette module (https://github.com/marionettejs/backbone.marionette/blob/master/docs/marionette.application.module.md), and have a collection of models (that don't get saved on the server) to list your menu entries. That way, you can manage the current entry by setting its model activeattribute to true (and checking that attribute in the view to highlight the current entry).
This is probably a lot to take in at first, but after a few more hours of working with Marionette it will all make sense...
(Shameless plug: I'm writing a book on Marionette that takes you from beginner to fully independent with Marionette. In there, I'll be covering this type of functionality, especially the menu management and how to highlight the current option. If you'd like to check it out, there's a free 55-page sample at http://samples.leanpub.com/marionette-gentle-introduction-sample.pdf and the book (which is still being written) is at https://leanpub.com/marionette-gentle-introduction)
I had the same question a time ago, what I strongly recommend is to get involved with Marionette layouts, collections, composite and collection views, regions and how to display content within templates.
Is not hard as you keep reading tutorials, I recommend reading lostechis.com which is a very educational blog from the creator of Marionette, Derick Bailey, also the Marionette Official website.
This is just about educating yourself doing tests and when some question comes to your mind search it and if not found dont doubt to ask it right here.
For the side bar and some other stuff you can just use JQuery-ui or Twitter bootstrap, it is very easy to integrate them with backbone/marionette views, but you just have to read to achieve that.
Which you luck.

Resources