web-dev-qa-db-ja.com

履歴状態をプッシュせずにAngularJSリダイレクト

以前の(非Angular)バージョンのアプリのレガシーURL形式をサポートするために必要なすべてをキャッチするルート(.when('/:slug', {...)など)があるAngularJSアプリに取り組んでいます。キャッチに応答するコントローラーはすべて、関連オブジェクトをプルしようとし、見つからない場合は、$location.pathメソッドを使用して404ページにリダイレクトします。これはユーザーを404ページに誘導することで機能しますが、ユーザーがブラウザーに戻ると、最初に404ページに強制したページに戻ってしまい、サイクルから抜けられなくなります。

私の質問は、1)この状況を処理するためのより良いパターンがあるか、または2)ブラウザーに履歴のプッシュ状態を強制しないユーザーを再ルーティングする方法があるかどうかです。

35
kyleder

"Replace Method"の下にある here で、履歴の状態に追加せずにURLを変更できます。これは、実質的にHTML5のhistory.replaceState()を呼び出すことと同じです。

$location.path('/someNewPath').replace();

URLを変更せずにビューを変更できることはわかりません。私が見つけたビューを変更する唯一の方法は、場所のパスを変更することです。

58
thrashr888

ルートシステムの通常の動作は、$routeサービスが$locationChangeSuccessイベントを監視し、ルートのロードを開始することです。テンプレートの読み込み、解決手順の実行、コントローラーのインスタンス化が完了すると、$routeChangeSuccessイベントがブロードキャストされます。その$routeChangeSuccessng-viewディレクティブによって監視されます。これにより、新しいルートが準備できたらテンプレートとスコープを交換することができます。

上記のすべてのことを踏まえると、現在のルートを更新し、ルート変更イベントを発行してビューを更新することにより、アプリケーションコードで$routeサービスの動作をエミュレートすることができます。

var errorRoute = $route.routes[null]; // assuming the "otherwise" route is the 404
// a route instance is an object that inherits from the route and adds
// new properties representing the routeParams and locals.
var errorRouteInstance = angular.inherit(
    errorRoute,
    {
        params: {},
        pathParams: {},
    }
);
// The $route service depends on this being set so it can recover the route
// for a given route instance.
errorRouteInstance.$$route = errorRoute;

var last = $route.current;
$route.current = errorRouteInstance;

// the ng-view code doesn't actually care about the parameters here,
// since it goes straight to $route.current, but we should include
// them anyway since other code might be listening for this event
// and depending on these params to behave as documented.
$rootScope.broadcast('$routeChangeSuccess', errorRoute, last);

上記は、「そうでなければ」ルートに「解決」ステップがないことを前提としています。また、$routeParamsを想定していないことも前提としています。これは、「その他の」ルートにはもちろん当てはまりますが、別のルートを使用する場合は当てはまらない場合があります。

上記のどれが実装の詳細とインターフェイスに依存しているかは不明です。 $routeChangeSuccessイベントは確かに文書化されていますが、ルートインスタンスの$$routeプロパティは、2ドル記号の名前が与えられたルートシステムの実装の詳細であるようです。 「その他の」ルートがキーnullを使用してルートテーブルに保持される詳細も、実装の詳細である可能性があります。したがって、これらすべてのことを踏まえると、この動作はAngularJSの将来のバージョンでは機能しなくなる可能性があります。

詳細については、 このイベントを処理するng-viewコード を参照できます。これは、最終的に、上記のコードが イベントを発行するコード とともに実行しようとしているものです。 =上記の例の基礎として使用したこと。これらのリンクから推測できるように、この投稿の情報は、AngularJSの最新のマスターブランチから派生したもので、執筆時点では1.2.0-snapshotとラベル付けされています。

3
Martin Atkins