2016-10-04 38 views
0

在Angular 1.5和角度ui路由器中,我想改變狀態的後退按鈕行爲以識別狀態的名稱而不是參數,因爲我有url/restaurant/1?param1 = value & param2 =在不刷新頁面的情況下動態更改的值。當屬性發生變化時,綁定和url不會改變,但是當我點擊後退按鈕時,它會轉到前一個參數狀態,而不是$ rootScope中按名稱保存的狀態。我已經調試了好幾個小時,目前我的解決方案有時只是有效,它不一致,因爲URL同步並不總是在時間上調用,因此狀態不會在URL更新時更新。我正確地識別後退按鈕何時被擊中,但它不刷新狀態。現在,我必須使用location.assign,但它只適用於某些時間。無論如何重新同步在角度ui路由器deferIntercept?

function bind(propGetters, 
 
    getUrl) { 
 
    let unwatch = this._$rootScope.$watchGroup(propGetters,() => { 
 
    let trimmedUrl = getUrl(); 
 
    let remove = this._$rootScope.$on('$locationChangeSuccess',() => { 
 
     this._$rootScope.disableBackButton = false; 
 
     remove(); 
 
    }); 
 

 
    this._$rootScope.disableBackButton = true; 
 
    if (!this._$rootScope._hitBackButton) { 
 
     this._$rootScope.shouldSync = false; 
 
     this._$location.url(trimmedUrl); 
 
    } 
 
    }); 
 

 
    return { 
 
    unbind(): void { 
 
     unwatch(); 
 
    } 
 
    }; 
 
    module.run(
 
    ($urlRouter, $rootScope) => { 
 
     $rootScope.shouldSync = true; 
 

 
     $rootScope.$on('$locationChangeSuccess', e => { 
 
     if ($rootScope.shouldSync) { 
 
      $urlRouter.sync(); 
 
     } else if (!$rootScope._hitBackButton) { 
 
      e.preventDefault(); 
 
     } 
 
     $rootScope.shouldSync = true; 
 
     }); 
 

 
     $rootScope.$on("$stateChangeSuccess", (event, toState, toParams, fromState, fromParams) => { 
 
     if ($rootScope.previousState) { 
 
      if ($rootScope.previousState.name !== fromState.name && !$rootScope.disableBackButton) { 
 
      $rootScope.previousState = lodash.merge(fromState, { params: fromParams }); 
 
      console.log($rootScope.previousState.name, 'previousState'); 
 
      } 
 
     } else { 
 
      this._$rootScope.previousState = lodash.merge(fromState, { params: fromParams }); 
 
     } 
 
     }); 
 

 
     $rootScope.$on('$locationChangeSuccess', (evt, newUrl, oldUrl) => { 
 
     $rootScope.actualPrevious = oldUrl; 
 
     if ($rootScope._hitBackButton) { 
 
      this._urlProvider.sync(); 
 
      $rootScope._hitBackButton = false; 
 
     } 
 
     }); 
 
     $rootScope.$on('$locationChangeStart', (evt, newUrl, oldUrl) => { 
 
     if ($rootScope.actualPrevious === newUrl && $rootScope.previousState && !$rootScope.disableBackButton && !$rootScope._hitBackButton) { 
 
      $rootScope.shouldSync = true; 
 
      event.preventDefault(); 
 
      console.log('hit back', $rootScope.previousState.name); 
 
      $rootScope._hitBackButton = true; 
 
      window.location.assign(this._urlService.getFullPath(this._$state.href($rootScope.previousState.name, $rootScope.previousState.params))) 
 
      // this._$state.go($rootScope.previousState.name, $rootScope.previousState.params, { reload: true }); - this doesn't seem to always work because of watch collisions? 
 
     } 
 
     }); 
 
     $urlRouter.listen(); 
 
    });

+0

我用'module.config(($ urlRouterProvider:angular.ui.IUrlRouterProvider )=> { $ urlRouterProvider.deferIntercept(); });' on config – evanjmg

+0

*我會建議:花些時間來創建一個plunker。這不僅會讓你的觀衆更多,而且可以增加獲得幫助的機會,但它也可以幫助你自己找到解決方案* –

回答

0

玩弄5小時後, 我發現這是最好避免使用deferIntercept一起,而不是reloadOnSearch:假像這樣

$stateProvider.state('app.restaurant', { url: '/restaurant/{slug}?param1&param2&param3', resolve: { param1: function 1, param2: function 2, param3: function 3 }, reloadOnSearch: false, params: { slug: { value: null }, }, controller: 'restaurantController', template: }); 注意,您必須使用deferIntercept而不是params。如果你的url改變,我強烈建議使用參數。後退按鈕應該可以正常工作與我的解決方案上面減去deferIntercept並加上reloadOnSearch:假

0
Full modified implementation: 

this._$rootScope.$on('$locationChangeStart', (evt, newUrl, oldUrl) => { 
 
     if (this._$rootScope.actualPrevious === newUrl && this._$rootScope.previousState && !this._$rootScope._hitBackButton) { 
 
     evt.preventDefault(); 
 
     this._$rootScope._hitBackButton = true; 
 
     this._$state.go(this._$rootScope.previousState.name, this._$rootScope.previousState.params); 
 
     } 
 
    }); 
 
    this._$rootScope.$on("$stateChangeSuccess", (event, toState, toParams, fromState, fromParams) => { 
 
     if (this._$rootScope.previousState) { 
 
     if (this._$rootScope.previousState.name !== fromState.name) { 
 
      this._$rootScope.previousState = lodash.merge(fromState, { params: fromParams }); 
 
     } 
 
     } else { 
 
     this._$rootScope.previousState = lodash.merge(fromState, { params: fromParams }); 
 
     } 
 
    }); 
 
    this._$rootScope.$on('$locationChangeSuccess', (evt, newUrl, oldUrl) => { 
 
     this._$rootScope.actualPrevious = oldUrl; 
 
     if (this._$rootScope._hitBackButton) { 
 
     this._$rootScope._hitBackButton = false; 
 
     } 
 
    });