34

My user can leave a state but before I want to show a modal dialog "Do you want to save?"

ONLY if the user data is dirty that means changed.

What I do NOT want is to stick a isDirty property in my EditController to the $rootScope go to the stateChangeStart event and check there for isDirty and then show/not the save dialog.

Prevent global variables says every javascript beginner book...

1.) What is then the pro way to prevent a state change without hacking the $rootscope?.

2.) Are there any helper libraries for ui-router which enhance the ui-router offering function hooks inside the controller to encapsulate the ui logic?

3 Answers 3

56

(1) According to the docs under State Change Events

 $rootScope.$on('$stateChangeStart', 
      function(event, toState, toParams, fromState, fromParams){ 
          event.preventDefault(); 
          // transitionTo() promise will be rejected with 
          // a 'transition prevented' error
 })

You could change $rootScope to $scope wherever appropriate and works.

Under Attach Custom Data to State Objects, you can pass on custom data.

(2) I'm not sure what you're asking but factories/services/providers would really help.

Sign up to request clarification or add additional context in comments.

7 Comments

Funny that I did not thought of the common local $scope always seeing all samples using $rootScope, maybe a bad example... your suggestion (1) worked!
I also just realized that I have to differentiate between logic run in the $rootState "stateChangeStart" only when a certain 'ToState' is activated (because I do not want to ask in any $scope.on("stateChangeStart) for a certain "ToState" ) and logic run when any State starts to change which I bind now to the local $scope to deal with the isDirty correctly.
How do you resume the event? Say I wanna do operations xyz and then resume the event and go to the wished state.
I think $scope may not work if the scope is isolated. But that's all
Doesn't $state.go(toState, toParams); initiate another state change inside this listener? @molerat, just add an if-statement and only prevent it if you want it prevented, otherwise let it pass through.
|
15

Using $transitions.onStart (angular-ui-router 1.0.0-rc) you can return a boolean. If false the transition will be cancelled.

$transitions.onStart({}, function (trans) { 
    var answer = confirm("Want to leave this page?")
    if (!answer) {
        return false;
    }
});

Here is the documentation: https://ui-router.github.io/ng1/docs/latest/modules/transition.html#hookresult

1 Comment

It's working, but I'm getting error in console TransitionRejection(type: 3, message: The transition has been aborted, detail: Hook aborted transition)
2

Though at the time of writing it is not a part of the stable release, the 1.0 release of the UI-router will use the return value of onEnter/onExit to prevent navigation.

See GitHub issue 2219

1 Comment

$scope.pn("$stateChangeStart") still works with 1.0-alpha/beta when referencing the included stateEvents.js file and requiring ui.router.state.events in your app's modules.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.