現在私たちのプロジェクトはデフォルトの$routeProvider
を使用しています、そして私はページをリロードせずにurl
を変更するためにこの "hack"を使用しています:
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();
ネスティングルートのためにrouteProvider
をui-router
に置き換えることを考えていますが、これをui-router
に見つけることはできません。
それは可能ですか - angular-ui-router
でも同じようにしますか?
なぜこれが必要なのですか?例を挙げて説明しましょう。
新しいカテゴリを作成するためのルートは、SAVEでclicking
の後に/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})
さて、解決しました:) Angular UIルーターにこの新しいメソッドがあります、$ urlRouterProvider.deferIntercept() https:/ /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();
}]);
私はこのメソッドは現在、masterバージョンのAngular ui router、オプションのパラメータを持つもの(これもいいですね、ところで)にしか含まれていないと思います。それはクローンを作成してソースからビルドする必要があります
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'
});
}]);
それが何をするかというと、パラメータの1つが欠落していても、状態を解決することができます。 SEOは目的、読みやすさは別の目的です。
上記の例では、doorsSingleを必須パラメーターにしたいと思いました。それらを定義する方法は明確ではありません。ただし、複数のオプションパラメータを指定しても問題なく機能するため、実際には問題ありません。議論はここにあります https://github.com/angular-ui/ui-router/pull/1032#issuecomment-4919609
この問題に多くの時間を費やした後、これが私が働いたことです
$state.go('stateName',params,{
// prevent the events onStart and onSuccess from firing
notify:false,
// prevent reload of the current state
reload:false,
// replace the last record when changing the params so you don't hit the back button and get old params
location:'replace',
// inherit the current params on the url
inherit:true
});
このセットアップは私にとって次の問題を解決しました:
.../
から.../123
に更新するときに、トレーニングコントローラが2回呼び出されることはありません。状態設定
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 ...
}
あなただけのURLを変更する必要があるが、状態の変更を防ぐ場合:
場所を変更します(履歴で置き換えたい場合は、.replaceを追加します)。
this.$location.path([Your path]).replace();
あなたの状態へのリダイレクトを防ぐ:
$transitions.onBefore({}, function($transition$) {
if ($transition$.$to().name === '[state name]') {
return false;
}
});
私はこれをやったが、ずっと前のバージョンで:UIルーターの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
})
呼び出し
$state.go($state.current, {myParam: newValue}, {notify: false});
それでもコントローラをリロードします。
それを避けるためには、パラメータを動的として宣言する必要があります。
$stateProvider.state({
name: 'myState',
url: '/my_state?myParam',
params: {
myParam: {
dynamic: true,
}
},
...
});
それならnotify
も必要ありません。
$state.go($state.current, {myParam: newValue})
十分です。ニアト!
dynamic
がtrue
の場合、パラメータ値を変更しても状態は開始または終了しません。解決は再取得されず、ビューも再ロードされません。[...]
これは、パラメータの値が変化したときにコンポーネントが自分自身を更新するUIを構築するのに役立ちます。
このようなことを試してください
$state.go($state.$current.name, {... $state.params, 'key': newValue}, {notify: false})