2012-08-02 18 views
17

通常のJavaScriptにはwindow.onbeforeunloadがあります。 HTML5ルートでAngularJSをエミュレートするにはどうすればよいですか?AngularJSでのwindow.onbeforeunloadの等価性。

$ beforeRouteChangeがありますが、私が知る限り、イベントをキャンセルすることはできません。

明確にする:window.onbeforeunloadは、ページから離れてナビゲートするためには動作しますが、ページ内ナビゲーションでは動作しません。 1つのコントローラから別のコントローラにHTML5履歴APIを介してアクセスするだけです。

答えて

15

キャンセル可能なイベントは$locationChangeStartです。

まだ文書化されていないので、$routeサービスにどのような影響があるかを説明する単体テストがあります。 https://github.com/angular/angular.js/blob/v1.0.1/test/ng/routeSpec.js#L63

これは、window.onbeforeunloadのようなユーザーには確認できません。同じ効果を得るには、独自のダイアログサービスを用意して場所変更プロセスを再開する必要があります(または、同期$window.confirmを使用するだけで済みます)。

+1

それは 'バックbutton'のために働くのか? – Freewind

+0

@Freewind戻るボタンのためにチェックインが2013年1月1日に有効になる:https://github.com/angular/angular.js/commit/dc9a580617a838b63cbf5feae362b6f9cf5ed986 – Nils

22

これを追加します。

$scope.$on('$destroy', function() { 
    window.onbeforeunload = undefined; 
}); 
$scope.$on('$locationChangeStart', function(event, next, current) { 
    if(!confirm("Are you sure you want to leave this page?")) { 
     event.preventDefault(); 
    } 
}); 
+5

角度ui-router '$ stateChangeStart'にはつかいます。そして、それは 'window.onbeforeunload'の場合に処理されるので、ページリフレッシュを処理しません。 –

+0

これは私のためには' $ scope'ではなく '$ rootScope'で' $ stateChangeStart'をリスンする必要がありました。これを行うと、現在のスコープが破棄されたときにこのイベントリスナを手動で登録解除する必要があることに注意してください( '$ scope。$ on( '$ destroy、...)')。 –

5

あなたは、角-UI-ルータを使用している場合は、$stateChangeStartの代わり$locationChangeStartを使用する必要があります。

+1

本当に本当です!ユーザーがページを離れるときではなく、コントローラーが「開始」されているときに、angle-ui-routerと共に '$ locationChangeStart'を使用します。 –

0

UI-Routerバージョン1.0.0以上を使用する場合、$stateChangeStartではなく$transitions.onStartを使用してください。ドキュメントtransition hooksを参照してください。 $stateChange*イベントは、バージョン1.0.0(source)のよう推奨されていません

すべての状態イベント、(すなわち$stateChange*や友人)今 を非推奨となり、デフォルトでは無効になっています。イベントをリスンする代わりに、 Transition Hook APIを使用してください。トランジション(source)を中止する

例コード:

$transitions.onStart({}, function(transition) { 
    if (transition.to().name === 'unreachable') { 
    return false; 
    } 
}