$state.go won't change route in angular after

2019-06-02 21:42发布

问题:

I have this code to confirm navigation away in angular, using angular-ui router:

$rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) {
        //checks if campaign has been modified without save. 
        //if yes state change needs to be confirmed by modal
        //otherwise simple navigates away
        event.preventDefault();
        // var _this = this;
        _this.toState = toState;
        _this.toParams = toParams;

        var modalInstance = bootstrapModals.confirm({
            title: "Exit without saving?",
            message: "You have changes to the campaign. Leave without saving?"
        });
        modalInstance.then(function(result) {
            $state.go(_this.toState.name, _this.toParams);
        }, function(error) {
            event.preventDefault();
        });

    });

However $state.go only displays the modal again, without any route change. The values in _this.toState.name and _this.toParams are correct.

What's the issue?

回答1:

You have an infinite loop on success. Every time you do a state change, you go back in the code causing the modal to be displayed again. You need to save the answer to prevent the modal from popping back up.



回答2:

It was still listening to routeChange. So I had to do it like this:

onRouteChangeOff = $rootScope.$on('$stateChangeStart', routeChange);

    function routeChange (event, toState, toParams, fromState, fromParams) {
        //checks if campaign has been modified without save. 
        //if yes state change needs to be confirmed by modal
        //otherwise simple navigates away

        // var _this = this;
        _this.toState = toState;
        _this.toParams = toParams;

        var modalInstance = bootstrapModals.confirm({
            title: "Exit without saving?",
            message: "You have changes to the campaign. Leave without saving?"
        });
        modalInstance.then(function(result) {
            //should stop listening to $stateChangeStart
            onRouteChangeOff ();
            $state.go(_this.toState.name, _this.toParams);
        }, function(error) {
            // event.preventDefault();
        });
        event.preventDefault();
    };


回答3:

Took me a while to get home to post this, sorry.

I'm not sure if the ModalInstance will work the same way, but this is the code using good 'ol confirm:

 $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) {
    //checks if campaign has been modified without save. 
    //if yes state change needs to be confirmed by modal
    //otherwise simple navigates awa
    // var _this = this;
    _this.toState = toState;
    _this.toParams = toParams;

    var result = confirm('are you sure you want to leave unsaved?');
    if(!result) {
        event.preventDefault();
    }

});

Don't prevent it first and don't use $state.go() if succeeding, only prevent if false.

You should be able to try something like this with the bootstrap modal.



回答4:

Check this

bootstrapModals.confirm({
        title: "Exit without saving?",
        message: "You have changes to the campaign. Leave without saving?",
        callback: function(result) {
            if(result) {
                //yes
            }else {
                //no
            }
        }
    });