Skip to content
This repository has been archived by the owner on Sep 20, 2020. It is now read-only.

Pinterest-like modal dialog behavior #11

Closed
MrOrz opened this issue Jul 3, 2014 · 6 comments
Closed

Pinterest-like modal dialog behavior #11

MrOrz opened this issue Jul 3, 2014 · 6 comments

Comments

@MrOrz
Copy link

MrOrz commented Jul 3, 2014

TL;DR -- The view of sticky state is cleaned up after $state.go() calls.


It's really exciting to see the discussion in angular-ui/ui-router#894 become modularized and usable. It's like a dream coming into reality. Thank you so much for this @christopherthielen !

The first thing I tried to build with ui-router-extras is a modal example. It slightly differs from the one in your example because I want to support navigation between modal views without dismissing & re-initializing the existing modal dialog, as well as supporting the "back" button in the browser.

Using $stateChangeStart instead of onEnter & onExit callbacks, it can be easily achieved:
http://plnkr.co/edit/4KqUNnRaUDNZO9t3VD0e


As a follow-up, I wanted to implement pinterest-like modal window using ui-router-extras. When the URL of individual items is visited directly, it should be presented in full-size, instead of being confined inside a modal.

However, this time the try is not successful.

I followed @ashaffer 's solution in the comment of the previous thread, resulting in the followig plunker:

http://plnkr.co/edit/8r7haRWCcpmT2ZmnSQCE

The core of the technique is to nest the "modal" state and the "full-size" state under a common parent state. In the parent state we redirect the user to either "modal" or "full-size" state according to where the user is from.

The full-sized view is working perfectly, as shown in the following link. When navigating to other items from the full-sized view, they were also shown in full-sized view, which is identical to the behavior of pinterest.

http://run.plnkr.co/plunks/8r7haRWCcpmT2ZmnSQCE/#/item/5

However, when a modal dialog is opened, the view of the sticky list state beneath is cleaned up, which can be reproduced by clicking any item in the following link:

http://run.plnkr.co/plunks/8r7haRWCcpmT2ZmnSQCE/#/

It seems that the effect of sticky goes away after the state redirect. Is this an intended behavior?

@christopherthielen
Copy link
Owner

Hi @MrOrz , I'm glad you're excited to use sticky states!

At first I thought you were running into issue #9 which is in 0.0.4-preview, but I see that you built your own JS from source.

This is definitely a bug. Somehow the "@" view is being clobbered from __inactives.locals. In the meantime, you can use a named view for the non-modal state tree. Have a look in this updated plunk: http://plnkr.co/edit/Qi1UDcFgTEeJmKa4liK2?p=preview (edited with correct url)

@christopherthielen
Copy link
Owner

@MrOrz I managed to track this down. This is actually not a bug, but rather a misunderstanding. UI-Router views are stored on the locals object. Each locals object on each state inherits its prototype from the parent state. Your "item" state is implicitly creating a "@" view, which hides the "@" view from the "__inactives" pseudostate.

I added debugging output to Sticky States which shows which views are loaded, and where in the prototypal inheritance chain they are registered. Example output from your plunk:
Views: (root.locals) / (__inactives.locals: '@' (list)) / (item.locals: '@' (item)) / (item.modal.locals: 'modal@' (item.modal))

This output shows the current state's inheritance chain. Views: (<state>.locals: '<viewname' (<source state of view>))

You can see that __inactives.locals has the root anonymous view '@' filled in from the list state. However, the item state also defined a '@' view, which hides the view from __inactives.

To solve this, you could either use a named view for the non-modal content, or you can define your item proxy state with no views:

  $stateProvider.state('item', {
    url: '/item/:id',
    views: {},
    resolve: {
      resolvedData: function($stateParams) {
        return $stateParams.id
      }
    },
    proxy: {  // Custom config processed in $stateChangeStart
      external: 'item.full',
      internal: 'item.modal'
    }
  });

@MrOrz
Copy link
Author

MrOrz commented Jul 6, 2014

views: {} works like a charm! Thank you for the detailed explanation of the inner workings of ui-routers.

@darkostanimirovic
Copy link

Hey guys, thanks for this, I got my pinterest- and facebook-like behaviour working, however, sometimes when I go from modal to sticky state using mouse Back button, page scrolls to top.
When pressing Escape it's all good.

What's interesting, scroll to top only happens when opening a modal (with photo resolved from backend API) the first time. When opening for the second time, resolve is cached, photo shows up immediatelly and scroll works as expected when modal is closed. (either by pressing Escape or Back button)

Any ideas where I should be looking at?

@TD-Stanley
Copy link

TD-Stanley commented Jan 12, 2017

Extremely sorry about pulling this back up from the dead:

http://plnkr.co/edit/Qi1UDcFgTEeJmKa4liK2?p=preview

I used your example in the plunker to get me in the direction I need., but how would I pass data back from the modal to the original state / controller? I've attempted using a service, and watching from the first controller, but the $watch doesn't work once the modal in invoked. I've also tried passing it back in fromsStateParams.

Given this use case, what is the best method to pass data back to the original controller from the modal?

@random-one
Copy link

random-one commented Jan 12, 2017

@TD-Stanley I hope you're not using exactly this version of ui-bootstrap, as the one in the plunkr. The module has more recent versions. The cause of your problem is that you're not using all the features ui-bootstrap offers. Please take a look at the documentation for version 0.13.1 which I saw is the first that offers a solution.
To be more detailed there is a property called bindToController that shares the scope of the controller that opens the $modal (and it's called $uibModal in newer versions) with the $uibModal instance.
Your issue is not for this module.

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

No branches or pull requests

5 participants