angularjs - navigationend - typescript change page




AngularJS UI路由器-更改網址,無需重新加載狀態 (5)

好的,解決 :) Angular UI路由器有這個新方法,$ urlRouterProvider.deferIntercept() github.com/angular-ui/ui-router/issues/64

基本上歸結為這個:

angular.module('myApp', [ui.router])
  .config(['$urlRouterProvider', function ($urlRouterProvider) {
    $urlRouterProvider.deferIntercept();
  }])
  // then define the interception
  .run(['$rootScope', '$urlRouter', '$location', '$state', function ($rootScope, $urlRouter, $location, $state) {
    $rootScope.$on('$locationChangeSuccess', function(e, newUrl, oldUrl) {
      // Prevent $urlRouter's default handler from firing
      e.preventDefault();

      /** 
       * provide conditions on when to 
       * sync change in $location.path() with state reload.
       * I use $location and $state as examples, but
       * You can do any logic
       * before syncing OR stop syncing all together.
       */

      if ($state.current.name !== 'main.exampleState' || newUrl === 'http://some.url' || oldUrl !=='https://another.url') {
        // your stuff
        $urlRouter.sync();
      } else {
        // don't sync
      }
    });
    // Configures $urlRouter's listener *after* your custom listener
    $urlRouter.listen();
  }]);

我認為這種方法目前只包含在角度ui路由器的版本中,它具有可選參數(這也很好,順便說一句)。 它需要從源代碼克隆和構建

grunt build

文檔也可以從源文件中獲取

grunt ngdocs

(它們被構建到/ site目錄中)// README.MD中的更多信息

似乎有另一種方法來做到這一點,通過動態參數 (我沒有使用過)。 許多信貸給nateabele。

作為旁注,以下是Angular UI路由器的$ stateProvider中的可選參數 ,我將它與上面的組合使用:

angular.module('myApp').config(['$stateProvider', function ($stateProvider) {    

  $stateProvider
    .state('main.doorsList', {
      url: 'doors',
      controller: DoorsListCtrl,
      resolve: DoorsListCtrl.resolve,
      templateUrl: '/modules/doors/doors-list.html'
    })
    .state('main.doorsSingle', {
      url: 'doors/:doorsSingle/:doorsDetail',
      params: {
        // as of today, it was unclear how to define a required parameter (more below)
        doorsSingle: {value: null},
        doorsDetail: {value: null}
      },
      controller: DoorsSingleCtrl,
      resolve: DoorsSingleCtrl.resolve,
      templateUrl: '/modules/doors/doors-single.html'
    });

}]);

這樣做可以解決一個狀態,即使其中一個參數丟失。 SEO是一個目的,另一個可讀性。

在上面的例子中,我想讓doorsSingle成為必需的參數。 目前還不清楚如何定義這些。 它可以與多個可選參數一起工作,所以不是一個真正的問題。 討論在這裡https://github.com/angular-ui/ui-router/pull/1032#issuecomment-49196090

目前我們的項目使用默認的$routeProvider ,並且我正在使用這個“hack”來更改url而無需重新加載頁面:

services.service('$locationEx', ['$location', '$route', '$rootScope', function($location, $route, $rootScope) {
    $location.skipReload = function () {
        var lastRoute = $route.current;
        var un = $rootScope.$on('$locationChangeSuccess', function () {
            $route.current = lastRoute;
            un();
        });
        return $location;
    };
    return $location;
}]);

並在controller

$locationEx.skipReload().path("/category/" + $scope.model.id).replace();

我正在考慮用ui-router替換routeProvider來嵌套路由,但是無法在ui-router找到它。

是否有可能 - 對angular-ui-router做同樣的事情?

為什麼我需要這個? 讓我用一個例子來解釋一下:
clicking SAVE後,創建新類別的路線是/category/new我顯示success-alert並且我想要更改路線/category/new/caterogy/23 (23 - 是存儲在db中的新項目的ID)


只要你可以使用$state.transitionTo而不是$state.go$state.go內部調用$state.transitionTo但自動將選項設置為{ location: true, inherit: true, relative: $state.$current, notify: true } 。 你可以調用$state.transitionTo並設置notify: false 。 例如:

$state.go('.detail', {id: newId}) 

可以被替換

$state.transitionTo('.detail', {id: newId}, {
    location: true,
    inherit: true,
    relative: $state.$current,
    notify: false
})

編輯:正如fracz所建議的,它可以簡單地為:

$state.go('.detail', {id: newId}, {notify: false}) 

如果您只需要更改網址但阻止更改狀態:

更改位置(如果您想在歷史記錄中替換,請添加.replace):

this.$location.path([Your path]).replace();

防止重定向到你的狀態:

$transitions.onBefore({}, function($transition$) {
 if ($transition$.$to().name === '[state name]') {
   return false;
 }
});

我做了這個,但很久以前版本:UI-router的v0.2.10像這樣的東西::

$stateProvider
  .state(
    'home', {
      url: '/home',
      views: {
        '': {
          templateUrl: Url.resolveTemplateUrl('shared/partial/main.html'),
          controller: 'mainCtrl'
        },
      }
    })
  .state('home.login', {
    url: '/login',
    templateUrl: Url.resolveTemplateUrl('authentication/partial/login.html'),
    controller: 'authenticationCtrl'
  })
  .state('home.logout', {
    url: '/logout/:state',
    controller: 'authenticationCtrl'
  })
  .state('home.reservationChart', {
    url: '/reservations/?vw',
    views: {
      '': {
        templateUrl: Url.resolveTemplateUrl('reservationChart/partial/reservationChartContainer.html'),
        controller: 'reservationChartCtrl',
        reloadOnSearch: false
      },
      '[email protected]': {
        templateUrl: Url.resolveTemplateUrl('voucher/partial/viewVoucherContainer.html'),
        controller: 'viewVoucherCtrl',
        reloadOnSearch: false
      },
      '[email protected]': {
        templateUrl: Url.resolveTemplateUrl('voucher/partial/voucherContainer.html'),
        controller: 'voucherCtrl',
        reloadOnSearch: false
      }
    },
    reloadOnSearch: false
  })

這個設置解決了以下問題:

  • .../.../123更新URL時,培訓控制器不會被調用兩次
  • 在導航到另一個狀態時,訓練控制器不再被調用

狀態配置

state('training', {
    abstract: true,
    url: '/training',
    templateUrl: 'partials/training.html',
    controller: 'TrainingController'
}).
state('training.edit', {
    url: '/:trainingId'
}).
state('training.new', {
    url: '/{trainingId}',
    // Optional Parameter
    params: {
        trainingId: null
    }
})

調用狀態 (來自任何其他控制器)

$scope.editTraining = function (training) {
    $state.go('training.edit', { trainingId: training.id });
};

$scope.newTraining = function () {
    $state.go('training.new', { });
};

培訓控制員

var newTraining;

if (!!!$state.params.trainingId) {

    // new      

    newTraining = // create new training ...

    // Update the URL without reloading the controller
    $state.go('training.edit',
        {
            trainingId : newTraining.id
        },
        {
            location: 'replace', //  update url and replace
            inherit: false,
            notify: false
        });     

} else {

    // edit

    // load existing training ...
}   




angular-ui-router