Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add parallell views and deactivated views #863

Closed
empaempa opened this issue Feb 5, 2014 · 5 comments
Closed

Add parallell views and deactivated views #863

empaempa opened this issue Feb 5, 2014 · 5 comments

Comments

@empaempa
Copy link

empaempa commented Feb 5, 2014

Hey!
I'm using Ionicframework (which uses angular-ui-router) to build an app. Native apps usually have parallell views (see the Spotify app, for example, where Search, Browse, Discover etc are parallell) and each of these parallell views have a history.

For example, if you go into Spotify's Search view, do a search and go on to the Artist view and then back to Search view again the search results are still there. Similarly if you do a search in the Search view then go to the Discover view and back to the Search view again, the search results are still there.

Would be great to be able to use named ui-views to create parallells (suggesting to use | (pipe) prefix):

<div ui-view="|search"/>
<div ui-view="|discover"/>

When a search-view is active, all other ui-views on the same level get's a "display:none" (or any other way of hiding, whatever is fastest).

The state could be defined as:

$stateProvider
  .state( "|search", { url: "/search", templateUrl: "search.html", controller: "searchCtrl" } );
  .state( "|discover", { url: "/discover", templateUrl: "discover.html", controller: "discoverCtrl" } ); 

And for ancestors (suggesting to use > separator to indicate that parent views are preserved):

.state( "|search>artist", { url: "/search/artist/:id", templateUrl: "artist.html", controller: "artistCtrl" } );
.state( "|search>album", { url: "/search/album/:id", templateUrl: "album.html", controller: "albumCtrl" } );

If you search and select an artist, the artist.html will appended as a child to the "|search" ui-view and the search.html content will be applied with "display:none" to be hidden. When going back, the artist.html will be removed from the DOM and the search.html will be shown again.

Does it sound reasonable? Feedback appreciated! Maybe the state name and the name of the ui-view shouldn't be connected as suggested?

@timkindberg
Copy link
Contributor

This is most likely a dupe of #562. Which is also related to #63.

@crrobinson14
Copy link

It might be... but all the related tickets are now closed and I think there's still a strong argument for behavior in this category. There have been statements made that developers should simply accept the cost of having to re-create a scope/controller/view when a user navigates from one state back to another previous state. There have even been statements made along the lines of "wouldn't you want fresh data anyway?"

These thoughts miss a huge use case: applications with live data feeds, either through WebSockets or similar. Consider a chat-room scenario where you could have 1..N views open, of which one is the main, "active" view (the one with the current URL). The others are "minimized" which means they're not drawn in the normal way but are still accessible, listening to their event streams, etc. You haven't "lost" anything.

Now the user closes the current chat room or hits "Back". It is not acceptable to have to re-create the entire thing from scratch - this is enormously inefficient and bad for the user experience. It's also a huge amount of unnecessary code when all that's required is a method of avoiding having the ui-view directive calling $destroy() on the scope. Even view "caches" can't work around this - as soon as you call $scope.$destroy(), you're sunk.

The only workaround right now is to move all of this management work to a service, leaving the controller to just handle stateless items like button-click actions. That does work, but it's totally opposite the point of a state-specific scope, which is where state-specific tracking data should be kept.

It seems like all you really need to enable what everybody else is brainstorming is a gate around the cleanupLastView() function here:

function cleanupLastView() {

All of the other ideas are great, but they're just more sophisticated ways of doing this. If you don't want to consider the more complex solutions, why not at least provide the raw component needed to do them without having to hack ui-router? This could easily be changed to support a callback - if not defined, this routine is run, otherwise the callback gets to do the same work (or not, if it chooses).

@christopherthielen
Copy link
Contributor

Have a look at the conversation in issue #894 then go here: http://christopherthielen.github.io/ui-router-extras/example/sticky/

@crrobinson14
Copy link

#894 is interesting and I reviewed it as part of determining how to solve this. It's extremely clever and I appreciate the work you put into it. But I was hoping not to use a fork -- we had a fairly decent "viewManager" that we had written internally, and the whole goal of switching to ui-router was to try to use a standard, Open Source mechanism instead.

I think I initially mis-read the trail of what you've done here - it looks like you've converted this from a fork to an add-on module, and it looks very sophisticated. I'm not sure if I can use it in my current project, but thanks for the contribution!

@eddiemonge
Copy link
Contributor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants