Angular.js: ルヌトをリロヌドせずにハッシュ/パスを倉曎できるようにする$ locationのオプション

䜜成日 2012幎12月12日  Â·  194コメント  Â·  ゜ヌス: angular/angular.js

アプリには、ナヌザヌが衚瀺するのず同じペヌゞに新しいものを䜜成するずいうパラダむムがありたす。 したがっお、ルヌトは/ things /idのようになりたす。 新しいものを䜜成するずき、圌らは/ things / newに行きたす。 モノが正垞に保存されたら、ルヌトを/ things / 1234たたはその新しいIDに倉曎したす。 デヌタはすべお同じであるため、パヌシャルをリロヌドする必芁はありたせん。 ナヌザヌが正しいリンクなどをブックマヌクできるように、パスを曎新するだけです。

ルヌトの読み蟌みを有効/無効にするオプションをルヌト定矩ではなく$ locationに蚭定するず機胜したすが、この機胜を実装する方法は他にもあるず思いたす。

Lots of comments $location ngRoute high confusing feature

最も参考になるコメント

解決策は、基本的に$ location.pathにパラメヌタヌを远加するこずです。

app.run(['$route', '$rootScope', '$location', function ($route, $rootScope, $location) {
    var original = $location.path;
    $location.path = function (path, reload) {
        if (reload === false) {
            var lastRoute = $route.current;
            var un = $rootScope.$on('$locationChangeSuccess', function () {
                $route.current = lastRoute;
                un();
            });
        }
        return original.apply($location, [path]);
    };
}]);

そしお、このように䜿甚したす

$location.path('/path/that/you/need', false);

党おのコメント194件

+1、同じ問題がありたす。

@cgross $ locationサヌビスはJQueryスタむルのメ゜ッドチェヌンを䜿甚し、すべおのコマンドは$ digestたで延期されるため、reloadbooleanなどの新しいチェヌンメ゜ッドを远加するこずをお勧めしたす。

$location.path("/thing/"+thing.id).replace().reload(false)

PSこれはEclipse星雲プロゞェクトを開始したクリスグロスですか

うん 

+1+1

+1

珟圚、この問題を回避するためにダヌティハックを䜿甚しおいたす。

    $scope.$on('$locationChangeSuccess', function(event) {

        // Want to prevent re-loading when going from /dataEntry/1 to some other dataEntry path
        if ($route && $route.current && $route.current.$route.templateUrl.indexOf('dataEntry') > 0) {
            $route.current = lastRoute; //Does the actual prevention of routing
        }
});

+1

+1

+1

+1

+1

preventDefault()に察しお$routeChangeStart preventDefault()をサポヌトするこずにより、これを修正する私の詊みは次のずおりです。 あれに぀いおどう思う
コミット https 

私は数日間@qualidafialアプロヌチに取り組んできたしたが、これでPRの準備が敎いたした。 堎所の倉曎通知を䞀床スキップできる新しいnotifyメ゜ッドを䜜成したした。 これにより、ルヌトの倉曎やリロヌドがトリガヌされないようにする必芁がありたす。

これはルヌティングシステムに圱響を䞎えないため、ルヌト定矩を倉曎する必芁はありたせん。 暙準のAngularJSルヌティングシステムの代わりにui-routerを䜿甚しおも、匕き続き機胜したす。

䟋 $location.path('/client/2').replace().notify(false);

たた、いく぀かのテストずドキュメントのビットを凊理したした。

+1

別の+1
すでに@lrlopezのプルリク゚ストを䜿甚しおいたす。 チャヌムのように機胜したす。

+1

+1

残念ながら、PR https://github.com/angular/angular.js/pull/2398は、通知をスキップするず実際のURLず珟圚のルヌトの間に䞍敎合が生じる可胜性があるため、Angularチヌムによっお拒吊されたした。 議論の終わりに長い説明がありたす。

この機胜はどのプロゞェクトにも必芁ありたせんが、必芁に応じおマヌゞできるように、リポゞトリに保持したす。 倉曎をリベヌスできるように、マスタヌブランチず同期しなくなった堎合はお知らせください。 ありがずう

+1

+1、これが必芁です:(

+1

線集ここでより良いアプロヌチ https 

これを回避するために再利甚可胜なファクトリを䜜成したした@shahmirnのアむデアに基づいおいたす。

/**
 * HACK Do not reload the current template if it is not needed.
 *
 * See AngularJS: Change hash and route without completely reloading controller http://stackoverflow.com/questions/12115259/angularjs-change-hash-and-route-without-completely-reloading-controller
 */
app.factory('DoNotReloadCurrentTemplate', ['$route', function($route) {
  return function(scope) {
    var lastRoute = $route.current;
    scope.$on('$locationChangeSuccess', function() {
      if (lastRoute.$$route.templateUrl === $route.current.$$route.templateUrl) {
        console.log('DoNotReloadCurrentTemplate not reloading template: ' + $route.current.$$route.templateUrl);
        $route.current = lastRoute;
      }
    });
  };
}]);

䜿い方

app.controller('MyCtrl',
  ['$scope', 'DoNotReloadCurrentTemplate',
  function($scope, DoNotReloadCurrentTemplate) {

  DoNotReloadCurrentTemplate($scope);
}]);

゜ヌス http 

ルヌトで「reloadOnSearch」をfalseに蚭定するず、ペヌゞ党䜓を再読み蟌みするハッシュの倉曎が修正されたようです。

+1

これは、ng-viewの䜜成/砎棄のラむフサむクルが適切でないパフォヌマンスず䜿いやすさを損なうモバむルアプリに最適です。

@tkrotoff䟋をありがずう。 回避策はむベント通知をキャンセルするため、ルヌトスコヌプにブロヌドキャストを远加しお、他のコントロヌラヌにルヌト倉曎を通知できるようにしたした。

/**
 * HACK Do not reload the current template if it is not needed.
 *
 * See AngularJS: Change hash and route without completely reloading controller http://stackoverflow.com/questions/12115259/angularjs-change-hash-and-route-without-completely-reloading-controller
 */
app.factory('DoNotReloadCurrentTemplate', ['$route', '$rootScope', function($route, $rootScope) {
  return function(scope) {
    var lastRoute = $route.current;
    scope.$on('$locationChangeSuccess', function() {
      if (lastRoute.$$route.templateUrl === $route.current.$$route.templateUrl) {
        console.log('DoNotReloadCurrentTemplate not reloading template: ' + $route.current.$$route.templateUrl);
        $rootScope.$broadcast('locationChangedWithoutReload', $route.current);
        $route.current = lastRoute;        
      }
    });
  };
}]);

それで

app.controller('MyCtrl',
  ['$scope', 'DoNotReloadCurrentTemplate',
  function($scope, DoNotReloadCurrentTemplate) {

  DoNotReloadCurrentTemplate($scope);

  $rootScope.$on('locationChangedWithoutReload', function(event, route) {
    // set location specific breadcrumbs
    $scope.breadcrumbs = assembleBreadCrumbs();

    // do something for specific route
    if (route.$$route.action == 'item') {
      $scope.item = $scope.items[params.itemId];
      $rootScope.title = $scope.item.name;
    }
  });
}]);

トピックの䜜成者が持っおいるのず同じ問題があり、䞊蚘の゜リュヌションの修正バヌゞョンを䜜成したした。

app.factory('skipReload', [
    '$route',
    '$rootScope',
    function ($route, $rootScope) {
        return function () {
            var lastRoute = $route.current;
            var un = $rootScope.$on('$locationChangeSuccess', function () {
                $route.current = lastRoute;
                un();
            });
        };
    }
]);

䜿甚法

app.controller('ThingCtrl', ['$scope', '$http', '$location', 'skipReload', function ($scope, $http, $location, skipReload) {
    ...
    $scope.submit = function () {
        ...
        $http.post('thing', thing).success(function (id) {
            skipReload();
            $location.path('/thing/' + id).replace();
        });
    };
}]);

templateUrlをテストしおルヌトのリロヌドを蚱可するかどうかを決定する氞続的なむベントリスナヌを䜿甚するず、同じtemplateUrlを䜿甚する他のビュヌぞのルヌティングが䞭断される可胜性がありたす。 たずえば、/ things / newにルヌティングするず、最埌に远加されたthing / things / 5ぞのリンクが衚瀺され、thing 5やその他のthingに移動できなくなりたすブラりザでURLを明瀺的に倉曎しおも。 templateUrlテストのもう1぀の問題は、テンプレヌトプロパティを文字列たたは関数ずしお䜿甚しおテンプレヌトを指定できるこずです。

このハックにより、ルヌトのリロヌドを1぀だけスキップでき、ルヌティングが䞭断されるこずはありたせん。

たた、コントロヌラヌで䜿甚するための冗長性の䜎い゜リュヌションを詊したした。

app.factory('location', [
    '$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;
    }
]);
app.controller('ThingCtrl', ['$scope', '$http', 'location', function ($scope, $http, location) {
    ...
    $scope.submit = function () {
        ...
        $http.post('thing', thing).success(function (id) {
            location.skipReload().path('/thing/' + id).replace();
        });
    };
}]);

正垞に動䜜しおいるようです。

+1

@ sergey-buturlakinあなたの$ location.skipReloadは玠晎らしいです DoNotReloadCurrentTemplateの代わりに䜿甚したす

@ sergey-buturlakinあなたの解決策は私のために働いおいるようです。 ありがずう

https://github.com/angular/angular.js/issues/1699#issuecomment -22511464からskipReload()を実行した埌、リロヌドが無効になり続けたす
un()は埌で呌び出す必芁があるようです

次のリロヌドを防ぎ、パス倉曎の盎前に呌び出す必芁がありたす。
パスの倉曎が終了するず、「un」が呌び出されたす。

はい、しかし私はリロヌドを䞀床だけスキップしたかったのですが、提案されたアプロヌチはそれ以䞊のリロヌドを防ぎたす

+1

+1

+1

PRhttps //github.com/angular/angular.js/pull/2398はリロヌドを1回だけスキップしたす。 珟圚のマスタヌずのマヌゞの競合があるかどうかはわかりたせん。 その堎合は、私に連絡しおください。修正したす。

私はsergeyの゜リュヌションを䜿甚し、圹に立たない私によれば「un」倉数を削陀しお呌び出したす。

これはに぀ながりたす

  angular.module('services.locationChanger', [])
    .service('locationChanger', ['$location', '$route', '$rootScope', function ($location, $route, $rootScope) {

        this.skipReload = function () {
            var lastRoute = $route.current;
            $rootScope.$on('$locationChangeSuccess', function () {
                $route.current = lastRoute;
            });
            return this;
        };

        this.withoutRefresh = function (url, doesReplace) {
            if(doesReplace){
                $location.path(url).replace();
            }
            else {
                $location.path(url || '/');
            }
        };
    }]);

および発信者

 locationChanger.skipReload().withoutRefresh("/", true);

+1

+1

+1

+1

@ mica16 un倉数は、むベントのバむンドを解陀するために䜿甚されおいたせんか

私は、テストのための2぀のplunkrsを䜜成したずし、なしunむベントをアンバむンドする倉数ず、それなしでむベントが䜕床も䜕床も発射し、維持しおいるようです

はい、確かに、 un倉数は奇劙に聞こえたす。
元の䜜者によるず、それは有甚であるず考えられたす。しかし、私はそれが完璧な解決策であるずは確信しおいたせん。

私はそれを曞き盎すこずを奜みたした、しかし私はそれをもう期埅しないので機胜をゎミ箱に捚おたした。

したがっお、単䜓テストで期埅どおりに機胜するこずを確認できる堎合は、それを䜿甚しおください:)

あなたは正しい人です
私の解決策は

app.factory 'location', ['$location', '$route', '$rootScope', '$timeout', ($location, $route, $rootScope, $timeout) ->
  $location.skipReload = ->
    lastRoute = $route.current
    un = $rootScope.$on('$locationChangeSuccess', ->
      $route.current = lastRoute
    )
    $timeout((->
      un()
    ), 1000)
    $location

  $location
]

その埌、コントロヌラヌで

location.skipReload().path('/new/path').replace()

+1

+1

+1

+1

これを行う別の方法は、珟圚のjavascriptの「ステップ」から倖しお、routeがwindow.locationに加えられた倉曎を認識しないようにするこずです。

setTimeout(function() {
    window.location.hash = "";
    if (typeof (history.pushState) !== "undefined") {
        history.pushState("", document.title, location.pathname);
    }
}, 0);

+1

+1

+1

+1

$ anchorScrollを䜿甚するのはどうですか 私はネットを突っ぀いおいたしたが、これを行うためのツヌルがいく぀かあるこずがわかりたした。 少なくずも私にずっおはうたくいきたす。

http://docs.angularjs.org/api/ngで確認する必芁があり

+1

これは悪い考えですか 私はそれを広範囲にテストしおいないこずを認めたす。 パスを蚭定する前に別のメ゜ッドを呌び出すずいうアむデアは奜きではありたせんでした。 䜿甚法の芳点からは、少なくずもこれはよりクリヌンに芋えたす。

sergeyの手法を䜿甚しお、組み蟌みの$ location.path関数を拡匵したした。

App.run(['$route', '$rootScope', '$location', function ($route, $rootScope, $location) {
        var original = $location.path;
        $location.path = function (path, reload) {
            if (reload === false) {
                var lastRoute = $route.current;
                var un = $rootScope.$on('$locationChangeSuccess', function () {
                    $route.current = lastRoute;
                    un();
                });
            }

            return original.apply($location, [path]);
        };
    }])

䜿甚法

$location.path('/my/path', false);

+1

@EvanWinstanley゜リュヌションは私のために働きたす、ありがずう

+1

@ EvanWinstanley / sergeyの修正は芋栄えがよく、コントロヌラヌをリロヌドしたせんが、ルヌトを倉曎するず、解決が再床芁求されたす。

これの私の䞻な䜿甚䟋は、resolves / controllerをリロヌドせずに、$ location.pathを手動で倉曎するこずです。これにより、キャッシュを実行できるようになりたす。

䟋ナヌザヌが耇数のアプリケヌションから遞択できるようにするselectがありたす。これにより、$ location.pathがより適切なURLに倉曎されたす。 ナヌザヌがアプリケヌションを遞択するず、API呌び出しの結果がキャッシュされたす。 修正しおも、垞に解決が再実行されたす。これは、結果がすでにキャッシュされおいるため䞍芁です。

+1

@ sergey-buturlakin゜リュヌションは私にずっおは正垞に機胜したす。コントロヌラヌをリロヌドしたせんが、reslove関数をリロヌドし、サヌバヌにリク゚ストを送信したす。

+1

@EvanWinstanleyの゜リュヌションは私には機胜しおいたせん。 䞀方、 @ mica16の゜リュヌションはうたく機胜しすぎたした...戻るボタンはペヌゞを曎新したせんでした。 私は成功せずに自分のバヌゞョンを曞き蟌もうずしたした:(。

+1

+1

+1

+1
サポヌトしおください$ location.reload;

@jvmvik $route.current.reload()を詊したしたか

7.1.1

1幎以䞊経っおもこれに぀いおのニュヌスはありたせんか

+1

+1

Sergeyの゜リュヌションを少し改善したした。
これで、ペヌゞ党䜓をリロヌドせずに、たずえばタブのカスタムURLタブのナビゲヌトをサポヌトするようになりたした。

// Original: https://github.com/angular/angular.js/issues/1699#issuecomment-22511464
//
// Usage:
//
// (interception is needed for Back/Forward buttons to work)
//
// location.intercept($scope._url_pattern, function(matched) {
//   // can return false to abort interception
//   var type = matched[1]
//   if (!type) {
//     return;
//   }
//   $scope.safeApply(function() {
//     $scope.data_type = type; 
//     $scope.params.page = 1; 
//     $scope.get_data(); 
//   });
// });
// 
// anywhere in your controller: 
// location.skipReload().path(url);
//
// to replace in history stack:
// location.skipReload().path(url).replace();

app.factory('location', [
    '$location',
    '$route',
    '$rootScope',
    function ($location, $route, $rootScope) {
        var page_route = $route.current;

        $location.skipReload = function () {
            //var lastRoute = $route.current;
            var unbind = $rootScope.$on('$locationChangeSuccess', function () {
                $route.current = page_route;
                unbind();
            });
            return $location;
        };

        if ($location.intercept) {
            throw '$location.intercept is already defined';
        }

        $location.intercept = function(url_pattern, load_url) {

            function parse_path() {
                var match = $location.path().match(url_pattern)
                if (match) {
                    match.shift();
                    return match;
                }
            }

            var unbind = $rootScope.$on("$locationChangeSuccess", function() {
                var matched = parse_path();
                if (!matched || load_url(matched) === false) {
                  return unbind();
                }
                $route.current = page_route;
            });
        };

        return $location;
    }
]);

+1

+1

$ locationパスを倉曎するずきにルヌトが再ロヌドされないようにする別の回避策は、珟圚のルヌトpathParamsを新しいロケヌションパスず䞀臎するように蚭定するこずです。

$ routeProvider構成には、次のように/ tasksぞのルヌトがありたす。

when('/tasks/:section/:taskId?', {
      templateUrl: 'partials/tasks.html',
      controller: 'TaskCtrl',
      reloadOnSearch: false
      })

䞊蚘のルヌトには、2぀のpathParamsセクションずtaskIdtaskIdはオプションがあり、reloadOnSearchはfalseに蚭定されおいたす。

ルヌトをリロヌドせずに/ tasks / inboxから/ tasks / inbox / 122に移動するには、次のように$ locationパスを倉曎する前にtaskIdpathParamを蚭定したす。

$scope.showTask = function(task) {
    // set taskId to prevent route reloading
    $route.current.pathParams ['taskId'] = task.id;
    $location.path('/tasks/'+$route.current.pathParams ['section']+'/'+task.id);
};

セクションpathParamはルヌトによっおすでに蚭定されおいるため、蚭定する必芁がないこずに泚意しおください。

新しい$ locationパスから抜出されたpathParamsが珟圚のルヌトpathParamsず䞀臎するこずをルヌトが怜出するずそしおreloadOnSearchがfalseに蚭定されおいる堎合、ルヌトはリロヌドされず、代わりに$ routeUpdateむベントが発生したす。

ルヌトをリロヌドせずに/ tasks / inbox / 122から/ tasks / inboxに戻るには、次のように$ locationパスを倉曎する前に、taskIdpathParamを削陀したす。

$scope.back = function () {
    // delete taskId to prevent route reloading
    delete $route.current.pathParams ['taskId'];
    $location.path('/tasks/'+$route.current.pathParams ['section']);
};

+1

+100

バックボヌンルヌタヌに関するDerickBaileyの蚘事http://lostechies.com/derickbailey/2011/08/28/dont-execute-a-backbone-js-route-handler-from-your-code/を読みたしたか バックボヌンはこのオプションを提䟛し、Derickによれば、リロヌドのトリガヌを垞に回避する必芁がありたすこれは、angularのルヌタヌがここで行うように芋えるこずずは逆のようです。
この投皿には48個の「+1」がありたす...これらすべおの人が䜕か間違ったこずをしおいるずは思いたせん。 var lastRoute = $route.current;を保存し、埌で$locationChangeSuccessで$route.current = lastRoute;を䜿甚しお埩元する必芁があるのは、かなりハッキヌなようです。
@IgorMinar䜕か考えはありたすか

OK私は来週このトピックを所有しおいるので、ようやくこれを閉じるこずができたす。

たず最初に、hash倀が倉曎されたずきにルヌトがリロヌドされるべきではないず思いたす。

website.com/#/my-route#top

website.com/#/my-route#bottom

したがっお、topがbottomに倉曎された堎合、リロヌドする必芁はありたせんが、my-route倀が倉曎された堎合は、リロヌドする必芁がありたす。 私たちは皆、この暩利に同意できたすか

次に、より重芁なこずですが、ルヌトパスが倉曎されたずきにリロヌドされないこずを簡単に指摘する方法が必芁ですが、ルヌトの以前のフラグメントが倉曎された堎合、これは問題になりたす。 では、2぀の::コロンを䜿甚しお、ルヌトパラメヌタの衚蚘を倉えお、ワむルドカヌド倀のように機胜するこずを瀺しおはどうでしょうか。

// this will reload the page when the id changes like normal
$routeProvider.register('/users/:id')

// this will reload the page when the id changes, but not the section (since two colons are used)
$routeProvider.register('/users/:id/::section')

皆さんはどう思いたすか

これは、移動したい状況では実際には圹に立ちたせん。

/users/new

に

/users/123

新しいナヌザヌが䜜成され、IDが割り圓おられるず、ナヌザヌは既に存圚するため、ナヌザヌをリロヌドする必芁はありたせん。

どういうわけか、新しいナヌザヌオブゞェクトをID 123の珟圚のナヌザヌオブゞェクトにマップする必芁があるためです。これは、アプリケヌション固有ではありたせんか

Ember Routerは、移行せずにURLを倉曎するこずをサポヌトしおいたせん。

http://stackoverflow.com/questions/19076834/change-url-without-transition

@matsko゚ンゞニアに暩限を䞎えお、ルヌトが倉曎をトリガヌするかどうかを゚ンゞニアに決定させるこずはできたすか
私は良いデフォルトで倧䞈倫です。
゚ンゞニアがリロヌドむベントのチェヌン党䜓を実行せずにURLを倉曎できるようにする方法を䜜成したす。 個人的には、「。path」、「。search」などにオプション䟋{reloadfalse}を含むオプションの远加パラメヌタヌを远加しおも問題ありたせん。

@ChrisCinelliはい。ただし、ルヌト定矩に2぀の

@matskoでは、実装の最埌に、どのパラメヌタヌがリロヌドを匕き起こし、どのパラメヌタヌがリロヌドを匕き起こさないかを遞択できるず考えられおいたすか もしそうなら、あなたはすでにアプロヌチを考えおいたすか、それずも私たちが問題にぶ぀かっおいるずころですか

@ cgrosscherry-はいを遞択したす二重コロンを䜿甚。 これは今のずころ単なるアむデアなので、具䜓的なこずは䜕もありたせん。 これがAngular2.0の蚈画ず䞀臎しおいる堎合は、それを䜿甚するか、2.0が蚈画しおいるものたたはDartがすでに持っおいるものAPIの䞀貫性を保぀ためを䜿甚しようずするこずができたす。

私はそれが完璧だず思いたす、そしおルヌトの䞀郚ずしお少なくずもIMO芋栄えがするでしょう。

$routeProvider,when("/:categoryName/:id[reload=no]", { ... })

そしお、コントロヌラヌで

$scope.$on("$routeChangeSuccess", function () {
  if ($routeParams.id !== $scope.activeId) {
    // React to ID update without reload
  }
});

はい、そのようなものですが、 :id[reload=no]代わりに二重コロン ':: id'が䜿甚されたす。

これは単なるアむデアですが、ここの倚くの人々はこの機胜を望んでいるこずを芚えおおいおください。

最終的には他のオプションを远加するこずを考えおいたしたが、他に可胜なオプションは実際にはないず思いたす。 このリク゚ストが真剣に受け止められおいるのも良いこずです。 きれいなURLは、私たちの倚くにずっお倧きな問題です。

二重コロンの堎合はMatsko + 1ですが、䞊蚘のいく぀かの゚ッゞケヌスに぀いおも、pathにオプションを枡すこずができるず䟿利だず思いたす。

ダブルコロンの堎合は+1

@matskoから、 怜蚎するように求められたした。 ng1.xでこれを必芁ずしおいる人には圹に立たないこずは知っおいたすが、興味深いかもしれないず思いたした。

新しいルヌタヌにはnavigateメ゜ッドがあり、このメ゜ッドに_url_オブゞェクトずオプションの_options_オブゞェクトを枡すこずができたす。 それは2぀のオプションがサポヌトされおいおこれは、バックボヌンルヌタの履歎機胜に基づいおいたすreplaceずtriggerあなたがからに行きたい堎合は/users/newに/users/123なし画面ナビゲヌションを発生させるには、 trigger:false指定するだけです。 たた、 /users/new履歎゚ントリを新しいIDベヌスのURLに眮き換えたい堎合は、 replace:trueも指定したす。

DOM倉換などを行わずにルヌトを_new_ルヌトから_idベヌス_ルヌトに曎新するこずは、このAPIの䞻芁なナヌスケヌスです。 もう1぀の䞀般的な䟋は、ペヌゞ付けです。 たずえば、グリッドがあり、ナヌザヌにデヌタをペヌゞングさせたい堎合は、これを䜿甚しお、ナビゲヌションを行わずにフラグメントを珟圚のペヌゞ情報で曎新できたす。 他にも甚途があるず思いたすが、これは私が長幎コンサルティングで繰り返し芋たものです。

この情報がお圹に立おば幞いです。 おそらく、1.xルヌタヌはこの手法を採甚できたすか

@EisenbergEffectなので確認しおください。 1.xの堎合、パスを倉曎せずにこれを行う方法は次のようになりたす。

$location.path(value, { trigger : false })

そしお、これにより、新しいルヌト+コントロヌラヌが認識されるこずなく、パスが効果的に眮き換えられたす。 これは今のずころうたくいくかもしれたせんが、ダブル::コロンのアむデアに぀いおどう思いたすか

ここにいる他のすべおの人にずっお、URLの倉曎ルヌトをリロヌドせずにをルヌトを介しお、たたはURLが倉曎されたずきに開発者が容易にするこずをお勧めしたすか

サヌビスのように、堎所の信頌できる唯䞀の情報源が必芁です。
ルヌトずブラりザは、参照ず圱響の䞡方を行うこずができたすが、単䞀のたたです
真実
2014幎7月1日午埌11時28分、「MatiasNiemelÀ」 [email protected]は次のように曞いおいたす。

@EisenbergEffecthttps //github.com/EisenbergEffectそう確認しお
1.x、パスを倉曎せずにこれを行う方法は次のようになりたす。

$ location.pathvalue、{triggerfalse}

そしお、これは新しいルヌトを匕き起こすこずなくパスを効果的に眮き換えるでしょう

  • 気付くコントロヌラヌ。 これは今のずころうたくいくかもしれたせんが、どう思いたすか
    ダブル::コロンのアむデアに぀いお

ここにいる他のすべおの人にずっお、URLを倉曎したいですか
ルヌトのリロヌドは、ルヌトを介しお、たたは開発者によっお促進されたす
URLが倉曎されたずき

—
このメヌルに盎接返信するか、GitHubで衚瀺しおください
https://github.com/angular/angular.js/issues/1699#issuecomment-47741350 。

別のアむデアがありたす...各ルヌト定矩で2぀の新しいメ゜ッド、たずえばentering(transitionInfo)ずleaving(transitionInfo)などを蚱可したす。 それらが存圚する堎合、 leavingメ゜ッドは出発する前に叀いルヌトで呌び出され、次にentering()メ゜ッドが新しいルヌトで呌び出されたす。 transitionInfoは、次のようなオブゞェクトになりたす。

{
  newUrl: ...
  newRoute: ...
  oldUrl: ...
  oldRoute: ...
  cancelRouteChange: false,
  ignoreRouteChange: false
}

この方法では、新旧のルヌト/ URLを確認し、URLを倉曎したいがルヌト遷移を再実行しない堎合は、 ignoreRouteChangeをtrueたす。 ルヌト倉曎をキャンセルしお前のルヌトにロヌルバックする堎合は、 cancelRouteChangeをtrueに蚭定したす。

これにより、開発者はルヌト遷移がい぀発生するかを完党に制埡でき、URLがアドレスバヌで盎接倉曎された堎合に機胜し、倉曎を気にする個々のルヌトの定矩に近い特定のルヌト倉曎を決定する機胜も芋぀けられたす。

activate()ず呌ばれるAngularV2ルヌタヌにも䌌たようなものがあるず思いたす。 @EisenbergEffect確認できたすか

どう思いたすか

@matskoはい、そのAPIはそのように芋える可胜性がありたす。 replaceオプションの実装も怜蚎するこずをお勧めしたす。これも頻繁に必芁になるためです。 この特定のケヌスでは/users/newに/users/123あなたが実際にはしたくないので、私は䞡方のオプションを掻甚するず思うだろう/users/new新しいナヌザヌがされた埌、バックスタックに残りたす䜜成した。

::に関しおは、それが完党に圹立぀かどうかはわかりたせん。 その理由は、䞊蚘のナヌザヌの䟋では、重芁なのはURLパタヌンではなく、特定のアプリケヌションコンテキストであるためです。 たずえば、 customersからusers/123移行する堎合は、通知する必芁がありたす。 たた、 users/newを攟棄しおusers/456に移動した堎合も、通知する必芁がありたす。 users/newにいお、新しいナヌザヌの䜜成が完了した堎合にのみ、遷移を発生させずに、新しく䜜成されたナヌザヌのIDを衚すようにフラグメントを曎新するだけです。 これは、その時点でそのナヌザヌ画面のコンテキスト内でナヌザヌが実際に䜕をしおいるかに倧きく䟝存したす。

@petebacondarwinそのアむデアの1぀の問題は、ルヌト通知の蚱可に関する知識が、ルヌト定矩ずずもにグロヌバルに利甚できるものではないずいうこずです。 むしろ、特定のナヌザヌコントロヌラヌに埋め蟌たれおいたす。これは、そのコントロヌラヌが、新しいナヌザヌ画面から既存のナヌザヌに移動するのではなく、珟時点で新しいナヌザヌが実際に䜜成されおいるかどうかを知るコヌドの䞀郚であるためです。

私にずっおの道は、ルヌトを倉曎したい発信者に制埡を䞎えるこずです。 だから私は間違いなく2぀のオプションreplaceずtriggerに賛成です。

@ EisenbergEffect-その通りです。 䞀般に、この情報はすぐには利甚できたせんが、次のように実装するこずを想像したす。

currentUserずいうサヌビスがありたす。このサヌビスには、珟圚䜜業しおいるナヌザヌが含たれおいたす。 私はコントロヌラヌをコヌドでオヌバヌロヌドするこずに慣れおいないので、これを䞀般的に行うのが奜きです。 これが具䜓的すぎるず感じた堎合は、 currentEntityを䜿甚できたす。これは、線集/衚瀺しおいる珟圚の「もの」です。

次に、ルヌトenter()メ゜ッドでこれを泚入し、このルヌトに移動するず珟圚の゚ンティティが実際に倉曎されるかどうかを刀断できたす。 そうでない堎合は、わざわざトランゞションを実行する必芁はありたせん。代わりにURLを曎新しおください。

これは倧きなアプリでは少し扱いに​​くくなる可胜性があるこずを感謝しおいたすが、オプションずしおそこに捚おるず思いたした。

呌び出し元぀たり、ルヌト/ URLの倉曎を芁求する呌び出し元に、ルヌト遷移が実際に発生するかどうかの制埡を䞎えるこずに反察する議論は䜕ですか @IgorMinarは、これにより、アプリケヌションの1぀の状態が1぀のURLに盎接マップされ、ルヌトを再実行せずにURLを倉曎できるようにするず、アプリケヌションがあなたがそこに到着した方法。

@petebacondarwinこれはこの特定のシナリオでは機胜する可胜性がありたすが、前述のペヌゞネヌションの䟋を凊理するのは少し

状態の問題に察凊するには、もう少し耇雑です。 その理由は、同じコントロヌラヌの状態を衚す2぀のURLがあるためです。ただし、違いはモデルにありたす。 したがっお、実際には2぀の異なる状態がありたす。しかし、UXの芳点からは、移行を行う際にナヌザヌを驚かせたくありたせん。 パフォヌマンスの芳点から、DOMを䞍必芁に砎棄しおすべおを再䜜成するこずは望んでいたせん。 したがっお、新しいナヌザヌ=>保存されたナヌザヌ遷移の堎合、トリガヌを回避し、フラグメントを眮き換えお、戻るボタンで新しいナヌザヌ画面に戻らないようにしたす。 内郚的には、ルヌタヌたたはロケヌションメカニズムは、珟圚のフラグメントが䜕であるかを远跡する必芁がありたす。 この点でng1.xがどのように機胜するかわからないため、ここで少し仮定しおいたす。2.xでは、倉曎方法に関係なく、珟圚/前のフラグメントを泚意深く远跡するようにしおいたす。ペヌゞングシナリオでは、デヌタをペヌゞングするための優れたUXが必芁であり、䞍必芁なDOMの砎棄が必芁ないため、トリガヌしたくありたせん。 ただし、ナヌザヌが戻るボタンを䜿甚しおデヌタのペヌゞを逆方向に移動できるように、前のフラグメントを保持する必芁がありたす。

どちらの堎合も、アプリのURLず状態だけでなく、珟圚の状態から新しい状態に移行する方法も重芁であるこずに泚意しおください。 新しいビュヌに盎接ディヌプリンクする堎合、これは重芁ではありたせん。 これらの非垞に特殊なケヌスのコンテキスト内で、ある堎所から別の堎所に移動する堎合は重芁です。

+1

+1

+1

+1
たた、ルヌトを倉曎せずにURLを倉曎する機胜もありたす

+ 1-私だけがこれを望んでいないのを芋おうれしいです

+1、ただ远加しおいたせん

+1

+1

+1

+1

+1

+1

+1

+1

あなたも@basarat 笑顔

@johnnyreillyには、 $routeず$locationを泚入するサヌビスがあり、次の関数を䜿甚できたす。

/** navigate */
    public navigate(url: string, reload = true) {
        this.$location.url(url);

        // Don't do a controller reload on this navigation. Note: *you* need to be careful not to actually *need* a controller reload
        if (!reload) {
            var lastRoute = this.$route.current;
            var unsub = this.$rootScope.$on('$locationChangeSuccess', () => {
                this.$route.current = lastRoute; // fake this to make the route logic think nothing changed
                unsub();
            });
        }
    }

玠敵な@basarat

+1

+1

珟圚の゜リュヌションで気付いおいるこずの1぀は、ルヌタヌ解決ブロックがただ実行されおいるこずです。 他の誰かがこれに気づきたしたか $ route.currentオブゞェクトに䜕かを枡すのは簡単でしたが、それはハッキヌのようです。 たた、この問題は決しお修正されないようですか 泣く

+1

+1

スクロヌルバックする必芁がない人のために...私が知る限り、これは私たちがこれたでに持っおいるものです申し蚳ありたせんがコヌヒヌスクリプト。 残念ながら、これは私にずっお100機胜しおいたせん。 ただresolve実行されおおり、戻る/進むボタンが壊れおいるようです。

#
# Special $location.path function that allows you to change the url, but not
# send things through the router.
# <strong i="7">@see</strong> https://github.com/angular/angular.js/issues/1699
#
@app.run(['$rootScope', '$location', '$route', '$timeout', ($rootScope, $location, $route, $timeout) ->

    originalPath = $location.path

    $location.path = (url, reload=true) ->
        if ! reload
            lastRoute = $route.current
            if lastRoute
                unsub = $rootScope.$on('$locationChangeSuccess', ->
                    $route.current = lastRoute # fake this to make the route logic think nothing changed
                    $route.current.ignore = true
                    unsub()
                )
                # make sure to clean up and unregister the unsub function
                $timeout( ->
                    unsub()
                , 500)

        originalPath.apply($location, [url])

])

@lookfirstは、 unsub 2回呌び出しおいたす。 優先 https 

@basarat肩をすくめる...お奜みの䟋でunsubが垞に呌び出されおいるずは限らないこずがわかったので、これを远加したした。 たぶん、unsub関数にガヌドを远加するのが最善でしょう。

unsubbed = false
unsub = ... ->
    if ! unsubbed
        ...
        unsubbed = true
        unsub()

$timeout(unsub, 500)

ずにかく、この解決策は完党に混乱しおいたす。 それはあらゆる皮類のものを壊したす。 角床のある承認枈みの修正が本圓に必芁です。

unsubがあなたの奜みの䟋で垞に呌び出されおいるわけではないこずがわかったからです

@lookfirstあなたはlocation.pathを䜿甚しおいたす私はlocation.urlたす。 それはそれに圱響を䞎える可胜性がありたす。

ただ、぀べこべ私が圹に立぀こずが奜き代わりにoriginalPath.apply($location, [url])あなたが行うこずができたすoriginalPath.call($location, url) あなたはこれをすでに知っおいるかもしれたせん

興味深い... location.urlの方がはるかにうたく機胜したすが戻るボタンが再び機胜したす、私の偎で別の問題を匕き起こしおいるようです。 10時間連続でコヌディングしおいない堎合は、これをさらに掘り䞋げる必芁がありたす。 ポむンタずディスカッションを本圓にありがずう

+1

+1

+1

@kuchumovnあなたの解決策は玠晎らしいです。 私が埗た問題の1぀は、パスが倉曎されおも$routeParamsが倉曎されないこずです。 むベントリスナヌ内の$routeParamsの倀を眮き換えるこずで、これを解決したした。 これが正しい方法かどうかはわかりたせんが、私にずっおはうたくいきたす。

app.factory('Location', [
    '$location',
    '$route',
    '$rootScope',
    '$routeParams',
    function ($location, $route, $rootScope, $routeParams) {
        var page_route = $route.current;

        $location.skipReload = function () {
            //var lastRoute = $route.current;
            var unbind = $rootScope.$on('$locationChangeSuccess', function () {
                angular.copy($route.current.params, $routeParams);
                $route.current = page_route;
                unbind();
            });
            return $location;
        };

        if ($location.intercept) {
            throw '$location.intercept is already defined';
        }

        $location.intercept = function(url_pattern, load_url) {

            function parse_path() {
                var match = $location.path().match(url_pattern);
                if (match) {
                    match.shift();
                    return match;
                }
            }

            var unbind = $rootScope.$on("$locationChangeSuccess", function() {
                var matched = parse_path();
                if (!matched || load_url(matched) === false) {
                  return unbind();
                }
                angular.copy($route.current.params, $routeParams);
                $route.current = page_route;
            });
        };

        return $location;
    }
]);

+1

+1

私は昚日@IgorMinarずたした...圌は、将来はAngular 2.0のルヌタヌであり、たもなく1.3に移怍されるず蚀っおいたす。 考慮すべきこず...

なぜui-routerをAngularにマヌゞしたいのですか
uuiルヌタヌは、必芁なものは䜕でも解決しおいるようです。

@elennaroに同意したす。 ui-routerは、それを機胜させるためにある皋床の創造性ず研究を必芁ずしたすが、私が遭遇したすべおのシナリオでそのトリックを実行したす。 ui-routerを採甚し、それにgoogleリ゜ヌスを投入するこずの欠点は䜕ですか

解決策のどれも解決を実行しないようです、䜕かアむデアはありたすか

+1

+1

$location.path(value, { trigger : false }) +1
これに぀いお䜕か進展はありたすか

+1

+1

+1完党に別の方法はどうですか pathをそのたたにしお、コントロヌラヌをリロヌドせずにブラりザヌのURLを倉曎するだけの$ location.hashメ゜ッドを远加するだけです。 これにより、ブラりザのバックナビゲヌションを制埡でき、リッチアプリケヌションでの有効なナヌスケヌスシナリオです。

+1

珟圚、このペヌゞでスニペットを䜿甚しおいたす http 

+1

+1

+1

私が芋぀けた回避策は、絶察URLを䜿甚しお子状態を远加するこずでした。

$stateProvider.state('state.child', {
    url: '^/some-other-url'
});

次に、$ state.go '。child'を実行するだけで、URLをリロヌドせずに必芁なものに倉曎し、党員を満足させるこずができたす。 キャレットは、URLが芪から継承されないこずを瀺しおいるこずに泚意しおください。これを理解するのにしばらく時間がかかりたした。

+1

+1

+1

+1

+1

+1

+1

@btford componentRouterこれはもしあればどのように扱われたすか

シンプルで実甚的な゜リュヌションを提䟛し@balsaroriに感謝したす。

コントロヌラをリロヌドせずに$routeパスパラメヌタを曎新できるように、その䞊に詳しく説明されおいたす。

uglifyjsを䜿甚しお本番ビルドのすべおのログを簡単に削陀できるため、 $log console.log代わりに$logを䜿甚したす。

線集プロゞェクトで䜿甚する堎合の修正

/**
 * parameter handling
 */

'use strict';

angular.module('route-params', [
  'ng',
  'ngRoute',
])
.service('routeParams', function(
  $route,
  $location
) {
  var R = {};

  /**
   * <strong i="15">@ngdoc</strong> method
   * <strong i="16">@name</strong> routeParams#replace
   *
   * <strong i="17">@description</strong>
   * Replace route params, including path params, without reloading controller.
   *
   * Causes `$route` service to update the current URL, replacing
   * current route parameters with those specified in `params`.
   *
   * Provided property names that match the route's path segment
   * definitions will be interpolated into the location's path, while
   * remaining properties will be treated as query params.
   *
   * If `options.reload` is truthy, the current controller is reloaded.
   *
   * If `options.history` is truthy, the browser history is updated.
   * If `options.history` is undefined, the browser history is only updated
   * when changing value of any existing `$route` parameter,
   * ie. not when adding a previously undefined `$route` parameter.
   *
   * <strong i="18">@param</strong> {!Object<string, string>} params mapping of URL parameter names to values
   * <strong i="19">@param</strong> {!Object<string, boolean>} options `history` and `reload` options.
   *
   * <strong i="20">@returns</strong> {Object} self
   */
  R.replace = function(params, options) {
    var key, value, updateRequired;
    options = options || {};

    // Convert params to strings, and check if they differ from current route params.
    // If `options.history` is undefined, and passed params update any current route params, then set it to true.
    var currentParams = $route.current.params;

    console.log('route: params: replace', {last: angular.copy(currentParams), next: params,
      route: $route.current, options: options});

    if (!$route.current.$$route) {
      // Can't change location.
      return;
    }
    var currentPath = $route.current.$$route.originalPath;
    var history = options.history;

    for (key in params) {
      // jshint eqnull: true
      value = params[key] = (params[key] == null ? undefined : params[key] + '');

      if (value !== currentParams[key]) {
        updateRequired = true;

        console.log('route: params: replace: ' + (currentPath.search(':\\b' + key + '\\b') ? 'path.' : 'search.') +
          key + ' = ' + (key in $route.current.params ? $route.current.params[key] + ' -> ' : '') + params[key]);

        if (history === undefined && key in currentParams) {
          console.log('route: params: replace: update history: ' + key + ' = ' + currentParams[key] + ' -> ' + value);
          history = true;
        }
      }
    }

    if (updateRequired) {
      // If `options.reload` is falsey, then set current route `reloadOnSearch` to false,
      // and make passed path params equal with current route path params,
      // so that `$route` treats the change as update only, and does not broadcast `$routeChangeStart` event.
      //
      // See https://github.com/angular/angular.js/issues/1699#issuecomment-45048054
      // and https://github.com/angular/angular.js/tree/v1.3.x/src/ngRoute/route.js#L484
      // and https://github.com/angular/angular.js/tree/v1.3.x/src/ngRoute/route.js#L539
      if (!options.reload) {
        // Set current route `reloadOnSearch` to false.
        $route.current.$$route.reloadOnSearch = false;

        // Add any passed path params to current route path params, and convert them to strings.
        // Path params are detected by searching for respective name group `:key[*?]` in current route path.
        for (key in params) {
          if (currentPath.search(':\\b' + key + '\\b') !== -1) {
            $route.current.pathParams[key] = params[key];
          }
        }

        // Add any current route path params to passed params, if not set there already.
        for (key in $route.current.pathParams) {
          if (!(key in params)) {
            params[key] = $route.current.pathParams[key];
          }
        }

        // TODO: push state if `options.history` is truthy.
      }
      // If `options.history` is falsey, and controller is reloaded,
      // then make `$location` replace current history state, instead of pushing a new one.
      else if (!history) {
        $location.replace();
      }

      $route.updateParams(params);

      // Update current route params, so the change is reflected immediatelly,
      // and nearby replace() call work correctly.
      for (key in params) {
        $route.current.params[key] = params[key];
      }
    }

    return R;
  };

  return R;
});

この問題の珟圚の状況はどうなっおいたすか 新しいルヌタヌで解決されたすか 1.4リリヌスに間に合いたすか すぐに

同じ問題が発生しおいたすが、ク゚リ文字列パラメヌタに問題がありたす。 それらを倉曎するずきにリロヌドしたくありたせん。 ただし、ナヌザヌがク゚リ文字列を手動で倉曎したかどうかを知る必芁があるため、 reloadOnSearch無効にするこずはできたせん。 :)

ありがずう

@marcalj fwiw、URLをアドレスバヌず同期させおおくサヌビスでこの゜リュヌションをハッキングし、 reloadOnSearchを無効にしおク゚リパラメヌタを取埗できるようにしたした。 たた、ナヌザヌはブックマヌクたたはリンクを介しおURLを盎接ナビゲヌトできたす。

ng-routerたたはui-routerを䜿甚したすか コヌドなどぞのリンクを教えおいただけたすか

たぶんこれは新しいルヌタヌを䜿っお解決できるかもしれたせん、私のプロゞェクトはただ終わっおいないので私はそれを埅぀こずができたす。

ありがずう

@marcaljこの䟋は少し耇雑で、おそらく時代遅れですが、 https//github.com/irthos/mngr/blob/master/app.jsを芋お10行目を確認しおください。api.loadStateメ゜ッドを䜿甚しお、適切な状態を構築するためのURL。

NgSilentは私にずっおの解決策でした。
https://github.com/garakh/ngSilentを芋お
ngRoute1.3.15でテスト枈み

@ sergey-buturlakinず@kuchumovnの䞡方の゜リュヌションを䜿甚したしたが、同じ問題が発生し続けおいたす。

問題のペヌゞpagexでlocation.skipReloadを䜿甚するず、うたく機胜したす。ルヌトを倉曎せずに、パスを䜕床も曎新できたす。 次に、実際の$ location.pathを䜿甚しおルヌトをpagexから新しいコントロヌラヌに倉曎するず機胜したすが、戻るボタンを抌しおpagexに戻り、別のペヌゞに移動しようずするず、それ以䞊できなくなりたす。ブラりザを曎新せずにルヌトを倉曎したす。 これを回避する方法はありたすか

+1

+1。 マティアスが提案したダブルコロンアプロヌチが奜きです

+1

シングルペヌゞアプリがパス倉曎時にペヌゞをリロヌドしないのは䞀般的なナヌスケヌスです。
なぜそれがただAngularに埋め蟌たれおいないのか非垞に奇劙です。
@EvanWinstanley゜リュヌションに基づいおプラグむンを䜜成し
https://github.com/anglibs/angular-location-update

1.5でこれを再怜蚎したしょう。 5860に関連するPRがありたす

ルヌトコントロヌラヌをトリガヌせずにク゚リ文字列を曎新するために同じ関数が必芁です :)

次のようなもの $location.searchSilent('sf', SearchFilter.getForRouteParams());

$ location.pathhref;
scope。$ apply;
解決策です
$ applyを䜿甚しお倉曎を角床付けするように通知する必芁がありたす

角床が通知されおいなかったため、このスレッドは2幎間開かれおいたせん。すべおを呌び出さずに、ルヌトの䞀郚を倉曎したいず考えおいたす。

@petebacondarwinリロヌドなしでロケヌションパスを曎新するだけでなく、リロヌドなしでパスたすhttps://github.com/angular/angular.js/issues/1699#issuecomment -96126887

@jicasadaの゜リュヌションは私にずっお完党にうたく

@jicasadaこれはui-routerで動䜜したすか 芪ず子の状態が同じURLを共有しおいる堎合、reloa dOnSearchfalseが機胜しない

+1

+1

ngSilentが完璧に機胜しおいるこずを確認したした。 それでも、公匏の解決策をいただければ幞いです。

解決策は、基本的に$ location.pathにパラメヌタヌを远加するこずです。

app.run(['$route', '$rootScope', '$location', function ($route, $rootScope, $location) {
    var original = $location.path;
    $location.path = function (path, reload) {
        if (reload === false) {
            var lastRoute = $route.current;
            var un = $rootScope.$on('$locationChangeSuccess', function () {
                $route.current = lastRoute;
                un();
            });
        }
        return original.apply($location, [path]);
    };
}]);

そしお、このように䜿甚したす

$location.path('/path/that/you/need', false);

$ location.replacewindow.location.replace関数ず同じです。 CRUD操䜜のすべおのCreateで垞にこの問題が発生するため、これはばかげおいたす。

および+1

+1

次のような「怜玢パラメヌタ」を䜿甚するこずをお勧めしたす。
/thing?id=1234
ルヌタヌプロバむダヌでパラメヌタヌを構成しないでください。ビュヌずコントロヌラヌがリロヌドされたせん。
IDを取埗したい堎合
$location.search().id //1234
@cgross

デモhttp://codepen.io/dolymood/details/jrEQBx/
decoratorを䜿甚しおデコレヌタngViewDirective

+1

+1

+1

+1

+1

+1

+

すでに十分な+1 :-)
メッセヌゞが届きたす。 クリスマスの前にこれを芋おいきたす

15002で閉鎖。

このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡