Angular.js: 경로를 다시 로드하지 않고 해시/경로 변경을 허용하는 $location 옵션

에 만든 2012년 12월 12일  ·  194코멘트  ·  출처: angular/angular.js

우리 앱에는 사용자가 사물을 보는 동일한 페이지에서 새로운 것을 생성하는 패러다임이 있습니다. 따라서 우리의 경로는 /thing/:id와 같습니다. 새로운 것을 만들 때 /thing/new로 이동합니다. 사물이 성공적으로 저장되면 경로를 /thing/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)

추신: Eclipse Nebula 프로젝트를 시작한 Chris Gross입니까?

네 :)

+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://github.com/redhotsly/angular.js/commit/f8ac46e6ac9d76cf855077d21b68b4c2c8043db1

저는 며칠 동안 @qualidafial 접근 방식을 연구해 notify 메서드를 만들었습니다. 이렇게 하면 경로 변경이나 다시 로드가 트리거되는 것을 방지할 수 있습니다.

이것은 라우팅 시스템에 영향을 미치지 않으므로 경로 정의를 변경할 필요가 없습니다. 표준 AngularJS 라우팅 시스템 대신 ui-router 를 사용하더라도 여전히 작동합니다.

예: $location.path('/client/2').replace().notify(false);

또한 몇 가지 테스트 및 문서화 작업을 수행했습니다.

+1

다른 +1
@lrlopez ' pull 요청을 이미 사용 중입니다. 매력처럼 작동합니다.

+1

+1

불행히도 알림을 건너뛰면 실제 URL과 현재 경로 간에 불일치가 발생할 수 있으므로 PR https://github.com/angular/angular.js/pull/2398 은 Angular 팀에서 거부되었습니다. 토론 끝에 긴 설명이 있습니다.

내 프로젝트에는 이 기능이 필요하지 않지만 원하는 경우 병합할 수 있도록 내 저장소에 보관하겠습니다. 변경 사항을 리베이스할 수 있도록 마스터 브랜치와 동기화되지 않는 경우 알려주세요. 감사 해요!

+1

+1, 이것이 필요합니다 :(

+1

편집: 더 나은 접근 방식: https://github.com/angular/angular.js/issues/1699#issuecomment -22511464

나는 이것을 우회하기 위해 재사용 가능한 공장을 만들었습니다(@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://stackoverflow.com/a/16496112/990356

경로에서 "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을 사용하는 다른 보기로의 라우팅이 중단될 수 있습니다. 예를 들어, /thing/new로 라우팅했고 보기에 마지막으로 추가된 /thing/5에 대한 링크가 표시되면 사물 5와 다른 모든 항목으로 이동할 수 없습니다(브라우저에서 명시적으로 URL 변경 포함). templateUrl 테스트의 또 다른 문제는 템플릿 속성(문자열 또는 함수)을 사용하여 템플릿을 지정할 수 있다는 것입니다.

이 해킹을 통해 정확히 한 번의 경로 재로드를 건너뛸 수 있으며 라우팅이 중단되지 않습니다.

또한 덜 장황한 (컨트롤러에서 사용하기 위해) 솔루션을 시도했습니다.

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

PR https://github.com/angular/angular.js/pull/2398 은 다시 로드를 한 번만 건너뜁니다. 현재 마스터와 병합 충돌이 있는지 모르겠습니다. 그런 경우에는 저에게 전화를 걸어주시면 해결해 드리겠습니다.

나는 쓸모없는 (나에 따르면) "un"변수를 삭제하고 호출하면서 sergey의 솔루션을 사용합니다.

이로 인해 다음이 발생합니다.

  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 변수가 사용되지 않습니까?

나는 테스트하기위한 두 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

이를 수행하는 또 다른 방법은 경로가 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를 수동으로 변경하는 것입니다.

예를 들어: 사용자가 여러 애플리케이션 중에서 선택할 수 있도록 하는 선택 항목이 있습니다. 그러면 더 좋은 URL을 위해 $location.path도 변경됩니다. 사용자가 애플리케이션을 선택하면 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
      })

위의 경로에는 두 개의 pathParams 섹션과 taskId(taskId는 선택 사항)가 있으며 reloadOnSearch는 false로 설정됩니다.

경로를 다시 로드하지 않고 /tasks/inbox에서 /tasks/inbox/122로 이동하려면 $location 경로를 다음과 같이 변경하기 전에 taskId pathParam을 설정하십시오.

$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 경로를 다음과 같이 변경하기 전에 taskId pathParam을 삭제하십시오.

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

+1

+:100:

백본 라우터에 대한 Derick Bailey 기사 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 생각이 있으신가요?

다음 주에 이 주제를 소유하고 있으므로 마침내 이 주제를 닫을 수 있습니다.

먼저 #hash 값이 변경될 때 경로가 다시 로드되어야 한다고 생각하지 않습니다.

website.com/#/my-route#top

website.com/#/my-route#bottom

따라서 상단이 하단으로 변경되면 다시 로드되지 않아야 하지만 my-route 값이 변경되면 다시 로드해야 합니다. 우리 모두 이 권리에 동의할 수 있습니까?

둘째, 더 중요한 것은 경로 경로가 변경될 때 다시 로드되지 않을 것이라는 점을 쉽게 지적할 수 있는 방법이 필요하지만 이전 부분의 경로가 변경되면 문제가 된다는 것입니다. 따라서 두 개의 :: 콜론을 사용하여 와일드카드 값처럼 작동함을 지적하는 경로 매개변수에 대해 다른 표기법을 사용하지 않는 이유는 무엇입니까?

// 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 예, 하지만 경로 정의에 두 개의 매개변수가 있으면 어떻게 됩니까? 다른 하나는 허용하면서 하나는 다시 로드하는 것을 방지할 수 있는 방법은 무엇입니까? 플래그는 전부 아니면 전무(all-or-nothing) 기능이 될 것입니다.

@matsko 그래서 구현 쪽에서 어떤 매개변수가 재로드를 유발하고 어떤 매개변수가 그렇지 않은지를 선별할 수 있다고 생각하고 있습니까? 그렇다면 이미 염두에 두고 있는 접근 방식이 있습니까, 아니면 바로 거기에 문제가 있습니까?

@cgross cherry-pick yes(이중 콜론 사용). 이것은 현재로서는 아이디어일 뿐이므로 구체적인 것은 없습니다. 이것이 Angular 2.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 는 Angular 2.0의 라우터에서 이 문제를 처리하는 방법에 대해 저에게 질문했습니다. ng1.x에 이것을 필요로 하는 사람들에게 도움이 되지 않는다는 것을 알고 있지만 그것이 당신에게 흥미로울 것이라고 생각했습니다.

새 라우터에는 _url_ 및 선택적 _options_ 개체를 전달할 수 있는 navigate 메서드가 있습니다. 이 두 가지 옵션을 지원하므로이 작업은, 백본 라우터의 역사 기능을 기반으로 replacetrigger 당신은에서 가고 싶은 경우 /users/new/users/123 하지 않고 화면 탐색을 일으키려면 trigger:false 를 지정하기 /users/new 새로운 ID 기반 URL을 기록 항목을, 당신은 또한 지정합니다 replace:true .

DOM 변환 등을 일으키지 않고 _new_ 경로에서 _id 기반_ 경로로 경로를 업데이트하는 것은 이 API의 주요 사용 사례입니다. 또 다른 일반적인 예는 페이지 매김입니다. 예를 들어 그리드가 있고 사용자가 데이터를 페이지로 넘기도록 하려는 경우 이를 사용하여 탐색을 유발하지 않고 현재 페이지 정보로 프래그먼트를 업데이트할 수 있습니다. 나는 다른 용도가 있다고 확신하지만 이것들은 내가 수년 동안 컨설팅에서 반복적으로 본 것입니다.

이 정보가 도움이 되기를 바랍니다. 아마도 1.x 라우터가 이 기술을 채택할 수 있을까요?

@EisenbergEffect 확인하기 위해. 1.x의 경우 경로를 변경하지 않고 이 작업을 수행하는 방법은 다음과 같습니다.

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

그리고 이것은 새로운 경로 + 컨트롤러가 인식하지 않고 경로를 효과적으로 대체합니다. 이것은 지금은 효과가 있지만 이중 :: 콜론 아이디어에 대해 어떻게 생각하십니까?

여기 있는 다른 모든 사람들의 경우, URL 변경(경로를 다시 로드하지 않고)을 용이하게 하고 싶습니까? 아니면 URL이 변경될 때 개발자가 경로를 통해 용이하게 하시겠습니까?

서비스와 같이 위치에 대한 중앙 정보 소스가 있어야 합니다.
경로와 브라우저는 참조하고 영향을 줄 수 있지만 단일 상태로 유지됩니다.
진실
2014년 7월 1일 오후 11시 28분에 "Matias Niemelä" [email protected]에서 다음과 같이 썼습니다.

@EisenbergEffect https://github.com/EisenbergEffect 그래서 확인합니다. 을위한
1.x에서 경로를 변경하지 않고 이 작업을 수행하는 방법은 다음과 같습니다.

$location.path(값, { 트리거 : 거짓 })

그리고 이것은 새로운 경로를 유발하지 않고 경로를 효과적으로 대체합니다.

  • 컨트롤러를 인식합니다. 지금은 효과가 있을 수 있지만 어떻게 생각하세요?
    double :: 콜론 아이디어에 대해?

여기 있는 다른 모든 사람들을 위해 URL을 변경하시겠습니까?
경로 다시 로드) 경로를 통해 또는 개발자가 촉진
URL이 변경되면?


이 이메일에 직접 답장하거나 GitHub에서 확인하세요.
https://github.com/angular/angular.js/issues/1699#issuecomment -47741350.

여기 또 다른 아이디어가 있습니다. 각 경로 정의에 대해 entering(transitionInfo)leaving(transitionInfo) 두 가지 새 메서드를 허용합니다. 존재하는 경우 leaving 메소드는 떠나기 전에 이전 경로에서 호출되고 entering() 메소드는 새 경로에서 호출됩니다. transitionInfo 는 다음과 같은 개체입니다.

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

이 방법에서는 이전 및 새 경로/URL을 확인한 다음 URL을 변경하지만 경로 전환을 다시 실행하지 않으려면 ignoreRouteChangetrue 합니다. 경로 변경을 취소하고 이전 경로로 롤백하려면 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 그 아이디어의 한 가지 문제는 경로 알림 허용에 대한 지식이 경로 정의와 함께 전역적으로 사용할 수 있는 것이 아니라는 것입니다. 오히려 컨트롤러가 새로운 사용자 화면에서 기존 사용자로 단순히 탐색하는 것과 비교하여 이 순간에 실제로 새 사용자가 생성되고 있는지 여부를 아는 코드 조각이기 때문에 특정 사용자 컨트롤러 내에 포함됩니다.

나에게 가야 할 길은 경로를 변경하려는 발신자에게 제어권을 부여하는 것입니다. 따라서 replacetrigger 두 가지 옵션을 선호합니다.

@EisenbergEffect - 맞습니다. 일반적으로 이 정보는 즉시 사용할 수 없지만 다음과 같은 방식으로 구현하는 것을 상상할 수 있습니다.

현재 작업 중인 사용자가 포함된 currentUser 서비스가 있습니다. 컨트롤러에 코드를 오버로드하는 것이 익숙하지 않기 때문에 일반적으로 이 작업을 수행하는 것을 좋아합니다. 이것이 너무 구체적으로 느껴지면 currentEntity 가 있을 수 있습니다. 이는 현재 편집/보고 있는 "물건"입니다.

그러면 route enter() 메서드는 이것을 주입하고 이 경로로 이동하는 것이 실제로 현재 엔터티를 변경하는지 여부를 결정할 수 있습니다. 그렇지 않은 경우 전환을 실행하지 않고 대신 URL을 업데이트하면 됩니다.

나는 이것이 큰 앱에서 약간 다루기 힘들 수 있다는 점에 감사하지만 옵션으로 버릴 것이라고 생각했습니다.

호출자(예: 경로/URL 변경을 요청하는 사람)에게 경로 전환이 실제로 발생하는지 여부에 대한 제어 권한을 부여하는 것에 반대하는 주장은 무엇입니까? @IgorMinar 는 이것이 애플리케이션의 한 상태가 하나의 URL에 직접 매핑된다는 제약을 깨고 경로를 다시 실행하지 않고 URL을 변경하도록 허용하면 애플리케이션이 당신이 거기에 도착한 방법.

@petebacondarwin 이는 이 특정 시나리오에서 작동할 수 있지만 위에서 언급한 페이지 매김 예제를 처리하는 것은 조금 더 바꾸지 않기를 원할 것입니다.

국가 문제를 해결하는 것은 조금 더 복잡합니다. 그 이유는 동일한 컨트롤러 상태를 나타내는 두 개의 URL이 있기 때문입니다. 하지만 차이점은 모델에 있습니다. 그래서 우리는 실제로 두 가지 다른 상태를 가지고 있습니다.... 하지만 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

현재 솔루션에서 주목하고 있는 한 가지는 라우터 확인 블록이 여전히 실행되고 있다는 것입니다. 다른 사람이 이것을 알아차리나요? $route.current 객체에 무언가를 전달하는 것은 쉬웠지만 해킹된 것처럼 보입니다. 또한 이 문제는 절대 해결되지 않을 것 같습니까? :울다:

+1

+1

뒤로 스크롤하고 싶지 않은 분들을 위해... 제가 말할 수 있는 한, 이것이 우리가 지금까지 가지고 있는 것입니다(죄송합니다 coffeescript). 불행히도, 이것은 나를 위해 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 두 번 호출하고 있습니다. 선호 : https://github.com/angular/angular.js/issues/1699#issuecomment -54931571

@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 귀하의 솔루션은 훌륭합니다. 내가 얻은 한 가지 문제는 경로가 변경된 후에도 $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 와 직접 이야기를

왜 ui-router를 각도로 병합하고 싶습니까?
uui 라우터는 필요한 모든 것을 꽤 해결하는 것 같습니다.

@elennaro에 동의합니다. ui-router가 작동하려면 약간의 창의성과 연구가 필요하지만 내가 만난 모든 시나리오에서 트릭을 수행합니다. ui-router를 채택하고 Google 리소스를 사용하는 것의 단점이 무엇인지 궁금하십니까?

솔루션 중 어느 것도 결의안, 아이디어를 실행하지 않을 것 같습니다.

+1

+1

$location.path(value, { trigger : false }) +1
이에 대한 진전이 있습니까?

+1

+1

+1 완전히 다른 방법은 어떻습니까? path()를 그대로 두고 컨트롤러를 다시 로드하지 않고 브라우저의 URL을 변경하는 $location.hash 메서드를 추가하기만 하면 됩니다. 이를 통해 브라우저의 뒤로 탐색을 제어할 수 있으며 풍부한 응용 프로그램에서 유효한 사용 사례 시나리오입니다.

+1

현재 이 페이지에서 스니펫을 사용하고 있습니다. http://joelsaupe.com/programming/angularjs-change-path-without-reloading/

+1

+1

+1

내가 찾은 해결 방법은 절대 URL이 있는 하위 상태를 추가하는 것입니다.

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

그런 다음 간단히 $state.go('.child') 를 수행하면 다시 로드하지 않고 URL을 원하는 URL로 변경하고 모두를 만족시킬 수 있습니다. URL이 부모로부터 상속되지 않는다는 것을 나타내는 캐럿이 있습니다. 이것을 알아내는 데 시간이 좀 걸렸습니다.

+1

+1

+1

+1

+1

+1

+1

@btford componentRouter 에서 이것이 어떻게 처리됩니까?

간단하고 효과적인 솔루션에 대해 @balsarori 에게 감사드립니다.

컨트롤러를 다시 로드하지 않고 $route 경로 매개변수를 업데이트할 수 있도록 그 위에 정교했습니다.

uglifyjs를 사용하여 프로덕션 빌드에 대한 모든 로그를 간단히 제거할 수 있으므로 $log console.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 참조
ngRoute 1.3.15로 테스트됨

@sergey-buturlakin과 @kuchumovn 솔루션을 모두 사용했는데 계속해서 같은 문제가 발생했습니다.

해당 페이지(pagex)에서 location.skipReload를 사용하고 훌륭하게 작동합니다. 경로를 변경하지 않고도 경로를 계속해서 업데이트할 수 있습니다. 그런 다음 실제 $location.path를 사용하여 경로를 pagex에서 새 컨트롤러로 변경하면 작동하지만 뒤로 버튼을 눌러 pagex로 돌아간 다음 다른 페이지로 이동하려고 하면 더 이상 브라우저를 새로 고치지 않고 더 이상 경로를 변경하십시오. 이 문제를 해결하는 방법이 있습니까?

+1

+1. 나는 Matias가 제안한 이중 콜론 접근 방식을 좋아합니다.

+1

단일 페이지 앱이 경로 변경 시 페이지를 다시 로드하지 않는 것이 일반적인 사용 사례입니다.
Angular에 아직 포함되지 않은 이유는 매우 이상합니다.
@EvanWinstanley 솔루션을 기반으로 플러그인을 만들었습니다.
https://github.com/anglibs/angular-location-update

이것을 1.5에서 다시 살펴보자. #5860에 관련 PR이 있습니다.

경로 컨트롤러를 트리거하지 않고 쿼리 문자열 업데이트에 동일한 기능이 필요합니다! :)

$location.searchSilent('sf', SearchFilter.getForRouteParams()); 와 같은 것

$location.path(href);
범위.$apply();
솔루션입니다!!
$apply()를 사용하여 각도 변경에 대한 정보가 필요합니다.

이 스레드는 Angular에 알림이 없었기 때문에 2년 동안 열리지 않았습니다. 모든 것을 호출하지 않고 경로의 일부를 변경하려고 합니다.

@petebacondarwin 리로드 없이 위치 경로 업데이트 뿐만 아니라 리로드 없이 경로 매개변수 업데이트가 있으면 좋을 것입니다... 위에서 구현한 것처럼 https://github.com/angular/angular.js/issues/1699#issuecomment -96126887

@jicasada 의 솔루션은 저에게 완벽하게 잘

@jicasada 가 ui-router에서 작동합니까? 상위 및 하위 상태가 동일한 URL을 공유하는 경우 reloa dOnSearch:false 가 작동하지 않는 ui-router에 버그를 제기했습니다. 업데이트된 요청 매개변수를 사용하여 하위 상태로 전환하면 상위 컨트롤러를 두 번 호출합니다.

+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 함수와 같습니다. 모든 Create in CRUD 작업에는 항상 이 문제가 있기 때문에 이것은 어리석은 일입니다.

(그리고) +1

+1

다음과 같이 "검색 매개변수"를 사용하는 것이 좋습니다.
/thing?id=1234
라우터 공급자에서 매개변수를 구성하지 마십시오. 보기 및 컨트롤러를 다시 로드하지 않습니다.
아이디 를 얻고 싶다면
$location.search().id //1234
@cgross

데모 http://codepen.io/dolymood/details/jrEQBx/
decorator 를 사용하여 ngViewDirective 데코레이터

+1

+1

+1

+1

+1

+1

+!

+1은 이미 충분합니다 :-)
우리는 메시지를 받습니다. 우리는 크리스마스 전에 이것을 볼 것입니다!

#15002에 의해 폐쇄되었습니다.

이 페이지가 도움이 되었나요?
0 / 5 - 0 등급