简体   繁体   中英

Angular 1 ui-router 1.0.24: change url programmatically without controller reload, keeping history and manual url change

I would like to keep synchronized the page url with the internal state of an angular 1 page that use ui-router 1.0.24.

When the page filter is changed, the page data are reloaded, then a $state.transitionTo() is called to synchronize the url with the new filter:

$state.transitionTo($state.current.name, self.getPageParams(), { /*location: 'replace',*/ reload: false, inherit: false, notify: false, custom: {urlChangedAfterReload: true} });

The page state is defined as:

  $stateProvider
    .state('page', {
      url: '/Page/:dateParam/:modeParam',
      params: {
        dateParam: {value: null, dynamic: false},
        modeParam: {value: 'READ', dynamic: false}
      },
      ...
    })

I tryed to mark the parameters as dynamic (with dynamic: true ): that options avoid the controller reload, but at the same time doesn't let to change the url manually and doesn't let to use the history (the parameters are dynamic, so ui-router ignore their change).

It is possible to enable the dynamic options only when I change the url programmatically, keeping it disabled when the user change the url by hand, by history or by a link?

I found a solution.

Before to change the url, I set all the parameters of the current page as dynamic (so the controller won't be reloaded).

this.reload = function() {
  ...
  $log.info('Updating url');
  const pageParams = $stateRegistry.states[$state.current.name].params;
  Object.keys(pageParams).forEach(paramName => pageParams[paramName].dynamic = true);
  $state.transitionTo($state.current.name, this.getPageParams());
};

Then, when the transition is completed, I set the dynamic parameter as false (so if the user will change the url or the browser history will be used, the page will be reloaded). onSuccess is called when the parameters are changed, onError otherwise.

this.$onInit = function () {
  ...
  const uiRouterOnSuccess = $transitions.onSuccess({}, () => {
    $log.info('onSuccess');
    const pageParams = $stateRegistry.states[$state.current.name].params;
    Object.keys(pageParams).forEach(paramName => pageParams[paramName].dynamic = false);
    return true;
  });
  const uiRouterOnError = $transitions.onError({}, () => {
    $log.info('onError');
    const pageParams = $stateRegistry.states[$state.current.name].params;
    Object.keys(pageParams).forEach(paramName => pageParams[paramName].dynamic = false);
    return true;
  });
  $log.info('$onInit');
  $scope.$on('$destroy', () => {
    $log.info('$destroy');
    uiRouterOnSuccess();
    uiRouterOnError();
  });
};

The getPageParams update the parameters with the filter values.

this.getPageParams = function() {
  const params = $state.current.params;
  params.dateParam = xxx;
  params.modeParam = yyy;
  return params;
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM