UI-Router - Change $state without rerender/reload of the page

前端 未结 3 368
一整个雨季
一整个雨季 2020-12-04 12:18

I\'ve been looking at these pages (1, 2, 3). I basically want to change my $state, but I don\'t want the page to reload.

I am currently in the page

相关标签:
3条回答
  • 2020-12-04 13:05

    For this problem, you can just create a child state that has neither templateUrl nor controller, and advance between states normally:

    // UPDATED
    $stateProvider
        .state('schedules', {
            url: "/schedules/:day/:month/:year",
            templateUrl: 'schedules.html',
            abstract: true, // make this abstract
            controller: function($scope, $state, $stateParams) {
                $scope.schedDate = moment($stateParams.year + '-' + 
                                          $stateParams.month + '-' + 
                                          $stateParams.day);
                $scope.isEdit = false;
    
                $scope.gotoEdit = function() {
                    $scope.isEdit = true;
                    $state.go('schedules.edit');
                };
    
                $scope.gotoView = function() {
                    $scope.isEdit = false;
                    $state.go('schedules.view');
                };
            },
            resolve: {...}
        })
        .state('schedules.view', { // added view mode
            url: "/view"
        })
        .state('schedules.edit', { // both children share controller above
            url: "/edit"
        });
    

    An important concept here is that, in ui-router, when the application is in a particular state—when a state is "active"—all of its ancestor states are implicitly active as well.

    So, in this case,

    • when your application advances from view mode to edit mode, its parent state schedules (along with its templateUrl, controller and even resolve) will still be retained.
    • since ancestor states are implicitly activated, even if the child state is being refreshed (or loaded directly from a bookmark), the page will still render correctly.
    0 讨论(0)
  • 2020-12-04 13:15

    Adding my answer because I think it's different enough from the accepted answer and may be useful to others:

    I had two states, begin and view, with a bunch of optional parameters being synced with the URL for view, like so:

    $stateProvider
        .state('begin',
            {
                url: '/',
                template: '<app-element></app-element>'
            })
        .state('view',
            {
                url: '/View?param1&param2&...&paramN',
                template: '<app-element></app-element>'
                params: {
                   param1: {
                       value: null,
                       squash: true
                   },
                   ...
                }
            });
    

    The link function for <app-element> would run any time I tried to sync the parameters using $state.go. Using {notify: false, reload: false} did not work for me. The link function still ran each time. I'm on 0.2 so dynamic isn't an available param option, either. I followed @b0nyb0y's suggestion and turned it into a parent/child relationship, which worked:

    $stateProvider
        .state('app',
            {
                url: '/',
                template: '<app-element></app-element>'
            })
        .state('app.view',
            {
                url: 'View?param1&param2&...&paramN',
                params: {
                   param1: {
                       value: null,
                       squash: true
                   },
                   ...
                }
            });
    
    0 讨论(0)
  • 2020-12-04 13:16

    REF: https://github.com/angular-ui/ui-router/wiki/Quick-Reference#statetransitiontoto-toparams--options

    $state.transitionTo('yourState', params, {notify: false});
    
    0 讨论(0)
提交回复
热议问题