Open State in modal


#1

Hi,

I have defined the following state definitions:

$stateProvider.state('default', {
    url: '/default',
    abstract: true,
    templateUrl: 'app/html/default.html'
})
    .state('default.entity-list', {
        url: '/entity-list',
        templateUrl: 'app/html/entity-home.html',
        controller: 'entityController'
    })
    .state('default.entity-details', {
        url: '/entity-details',
        templateUrl: 'app/html/view_entity.html',
        controller: 'ViewEntityCtrl'

    })

The default.html file defines a ion-nav-view and so it works perfectly when going to entity-details or entity-list states, but i want to open entity-details state not inside the ion-nav-view but inside a modal using $ionicModal. The entity-details has also some child states and views.

Trying to open the modal using the state template instead of using a state works but i don’t have any way to assign the state $scope or controller, and i need to do that. Apparently using ng-controller inside the state template does not work also.

All that i have tried has failed, could you please help me?? I need an idea of how (if possible) use a modal instead of a ion-nav-view to hold a state or how to specify the controller to be used by the contents of ionicModal.Please remember that inside the entity-details there are child views.

Regards


#2

I don’t know if this answers your question completely, but what i do to show a Modal from different states, is define the modal template on $rootScope (on the app.js file), like so:

  var scope = $rootScope;

  $ionicModal.fromTemplateUrl('templates/login.html', {
    scope: scope,
    animation: 'slide-in-up',
    backdropClickToClose: false,
    hardwareBackButtonClose: false
  }).then(function(modal) {
    scope.modal = modal;
  });

The only thing is, when i need to call it, i use a $timeout to have the app wait (just like a milisec) to load the $rootScope, it feels a bit hackish, but i didn’t find any alternative to do so… On the controller i want to call the modal then it is like:

$scope.modalLogin = function(){
   $rootScope.modal.show();
};
$timeout($scope.modalLogin, 0);

As i said, i don’t know it this helps, but it’s what i do.
Best of luck to you :wink:


#3

Hi

Thanks for the answer, unfortunately i don’t need to show a modal from a state, but to use the modal as holder of the state’s template and controller.

Thanks anyway for your time and sorry for the late reply

Regards, Raul


#4

Oh i see, sorry haha. So you want to use a state’s template but with a modal? I don’t get where that would be useful… Can you explain a bit further please?


#5

Don’t worry i know is a strange requirement :smile:

I have a “legacy” app written with ionic and angular by people that had zero knowledge of both so as you can imagine the code is a real mess and filled with anti patterns, for example they used the main view’s scope as a global repository for code to be shared between controllers. And all views but the main one are implemented as modals.

I have successfully migrated most of the app to proper states using ui-router but the main view has a initialization step on the controllers body that is very expensive and i can’t modify it. The initialization is attached to a document.ready listener

So, even if the controller is not refreshed every time I go back to the main view the init function is fired and the transition gets delayed for about 5 seconds. Which is not acceptable, so I thought in using a modal, because closing a modal doesn’t fires the document ready listener.

I know the best approach is to properly rewrite the app and move the initialization code to a proper data model layer implemented with angular services but for now i am not allowed to do that.

For the moment the only workaround (apart from the modal ) is using abstract states and making the main view a parent of all the rest.

As you see not a common (or even a desirable) use case but is the one i have to deal with :wink:

Regards, Raúl


#6

Oh wow, i never seen that case before haha. Well, if any help, i think you could do something about a $rootScope? Keeping the ‘main view variables’ that are open for all controllers in a rootScope… Maybe you could even keep global functions there. If this initialization step you are talking about could be implemented into $rootScope, it would be kinda easy to go from there, but i don’t know if ideal or not. Well, anyways, i wish you good luck, i don’t think i will be able to help you much further, but i am interested in how things go with your effort haha. If possible, keep me posted.

Thanks,

Bruno


#7

For the record, I don’t think this is an unusual use case at all. My app has a list of items and when creating a new item for the list, I want to open a modal and load in a bunch of data from a REST API to populate some slideboxes in the modal.

This is a pivot from the way my app used to work when the “create” screen was on a tab. It previously used resolve to get all the REST data before showing the tab. Now I’d like to reuse that state code to populate the modal.


#8

I’ll definitely second this question.
My use-case is the conversion of a smartphone app (in which the detail of an item is opened as a sub view) to a tablet one, in which the detail is not opened as a new view but as a modal.

I currently have hacked my way by encapsulating all of the logic/view in a directive, reusing it in the “modal” style or in the old controller, but it kinda feel “not good”.
Moreover, for the modal I’ve had to recreate all the navigation manually.