web-dev-qa-db-ja.com

ビューを再レンダリングせずにAngular JSのURLを更新する

私はAngularJSでダッシュボードシステムを構築していますが、$location.path経由でURLを設定する際に問題が発生しています

ダッシュボードには、多数のウィジェットがあります。それぞれをクリックすると、最大化された大きなビューが表示されます。ユーザーがウィジェットを最大化したダッシュボードにリンクできるように、ディープリンクを設定しようとしています。

現在、/dashboard/:dashboardId/dashboard/:dashboardId/:maximizedWidgetIdのような2つのルートがあります

ユーザーがウィジェットを最大化すると、$location.pathを使用してURLを更新しますが、これによりビューが再レンダリングされます。すべてのデータがあるため、ビュー全体をリロードするのではなく、URLを更新するだけです。ビューを再レンダリングせずにURLを設定する方法はありますか?

HTML5Modetrueに設定されます。

79
Ian Muir

実際、ビューはURLを変更するたびにレンダリングされます。つまり、$ routeProviderがAngularでどのように機能するかですが、ビューを再レンダリングしないクエリ文字列としてmaximizeWidgetIdを渡すことができます。

App.config(function($routeProvider) {
  $routeProvider.when('/dashboard/:dashboardId', {reloadOnSearch: false});
});

最大化するウィジェットをクリックすると:

<a href="#/dashboard/1?maximizeWidgetId=1">Maximum This Widget</a>
or
$location.search('maximizeWidgetId', 1);

アドレスバーのURLはhttp://app.com/dashboard/1?maximizeWidgetId=1に変わります

URLで検索が変更されたとき(ウィジェット間で)を監視することもできます

$scope.$on('$routeUpdate', function(scope, next, current) {
   // Minimize the current widget and maximize the new one
});
130
codef0rmer

$ routeProviderのreloadOnSearchプロパティをfalseに設定できます。

重複する可能性のある質問: AngularJSでコントローラーをリロードせずにパスを変更できますか?

よろしく

9
bdavidxyz

コントローラをリロードせずにフルパスを変更する必要がある人向け

プラグインは次のとおりです。 https://github.com/anglibs/angular-location-update

使用法:

$location.update_path('/notes/1');
6

同様のシナリオでは、組み込みルートの代わりにAngular UI Router を使用しています。コントローラを再インスタンス化し、ビュー全体を再レンダリングするようには見えません。

3
DreamSonic

これは古い質問だと思いますが、答えを見つけるのに1日半かかったので、ここに行きます。

angular-ui-router を使用する場合、パスをクエリ文字列に変換する必要はありません

現在、 バグと見なされる場合があります により、状態にreloadOnSearch: falseを設定すると、ビューをリロードせずにルートを変更できるようになります。 GitHubユーザーlmessingerは、そのデモを提供するのに十分なほど親切でした。上記のリンクにある彼のコメントからリンクを見つけることができます。

基本的にあなたがする必要があるのは:

  1. ngRouteの代わりにui-routerを使用します
  2. 州で、reloadOnSearch: falseで希望するものを宣言します

私のアプリには、カテゴリ一覧ビューがあり、次のような状態を使用して別のカテゴリに移動できます。

$stateProvider.state('articles.list', {
  url: '{categorySlug}',
    templateUrl: 'partials/article-list.html',
    controller: 'ArticleListCtrl',
    reloadOnSearch: false
  });

それでおしまい。お役に立てれば!

3
ohanhi

実装方法:
(ほとんどの場合、サブパーツではなくルート全体を変更する必要がある場合のソリューション)

メニュー(menuPage)を含むページがあり、ナビゲーションでデータを消去しないでください(各ページに多くの入力があり、データが誤って消えるとユーザーは非常に不満になります)。

  1. $ routeProviderをオフにする
  2. mainPageコントローラーでカスタムディレクティブ属性を持つ2つのdivを追加します-各ディレクティブには「templateUrl」と「scope:true」のみが含まれます

     <div ng-show="tab=='tab_name'" data-tab_name-page></div>
    
  3. mainPageコントローラーには、ルーティングをシミュレートする行が含まれています。

    if (!$scope.tab && $location.path()) {
        $scope.tab = $location.path().substr(1);
    }
    $scope.setTab = function(tab) {
        $scope.tab = tab;
        $location.path('/'+tab);
    };
    

それで全部です。各ページに個別のディレクティブがあるのは少しLittleいですが、ディレクティブでの(機能としての)動的なtemplateUrlの使用は、ページの再レンダリング(および入力データの喪失)を引き起こします。

2
OZ_

使用するアイデアがあります

window.history.replaceState( 'Object'、 'Title'、 '/ new-url');

これを行うと、ダイジェストサイクルが発生すると、完全に混乱します。ただし、angularが期待する正しいURLに戻す場合は問題ありません。したがって、理論的には、angularが期待する正しいURLを保存し、ダイジェストが発生する直前にそれをリセットできます。

ただし、これはテストしていません。

私があなたの質問を正しく理解したら、あなたは、

  1. ユーザーが/ dashboard /:dashboardIdにいるときにウィジェットを最大化し、ウィジェットを最大化します。
  2. ユーザーが/ dashboard /:dashboardId /:maximizedWidgetIdに戻って、ウィジェットが最大化されていることを引き続き確認できるようにする必要があります。

RouterConfigで最初のルートのみを構成し、 RouteParams を使用して、最大化されたウィジェットがこの構成されたルートのコントローラーのparamsで渡されるかどうかを識別し、paramとして渡されるものを最大化できます。ユーザーが初めて最大化する場合、この最大化されたビューのURLをUIのmaximizedWidgetIdと共有します。

パスを更新するために$ location(ネイティブロケーションオブジェクトの単なるラッパー)を使用している限り、ビューを更新します。

0