뷰를 다시 렌더링하지 않고 Angular JS에서 URL 업데이트


79

AngularJS에서 대시 보드 시스템을 구축 중이며 다음을 통해 URL을 설정하는 데 문제가 있습니다. $location.path

대시 보드에는 많은 위젯이 있습니다. 클릭하면 각각 더 큰 최대화보기가 표시됩니다. 사용자가 위젯을 최대화 한 상태에서 대시 보드에 연결할 수 있도록 딥 링크를 설정하려고합니다.

현재, 우리는이 개 경로가 같은 모양 /dashboard/:dashboardId/dashboard/:dashboardId/:maximizedWidgetId

사용자가 위젯을 최대화하면을 사용하여 URL을 업데이트 $location.path하지만 이로 인해 뷰가 다시 렌더링됩니다. 모든 데이터가 있으므로 전체보기를 다시로드하지 않고 URL 만 업데이트하려고합니다. 뷰를 다시 렌더링하지 않고 URL을 설정하는 방법이 있습니까?

HTML5Mode로 설정됩니다 true.


1
데이터가 클라이언트 측의 경로 변경에서 살아남도록하려면 데이터를 서비스로 푸시하지 않는 이유는 무엇입니까?
Riko

답변:


133

실제로 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
});

1
대답이 받아 들여지면 ": param"항목없이 별도의 질문을 만들 것입니다. 그냥 어리석은 질문 : 뷰를 다시 렌더링하지 않는 방법.
OZ_

2
이 경우 angular-ui-router 가 확실한 선택이 될 것이라고 생각 합니다.
codef0rmer 2013-08-31

1
$routeUpdate이벤트를 사용하고 있습니다. $routeChangeStart다른 위치로 이동할 때 트리거되는 것 같습니다 .
lucassp 2013-08-31

@kuchumovn : 불행히도 우리는 여전히 2014 년입니다. Angular 2.0은 당신이 의도 한 것을 할 수있는 개조 된 라우팅 (아마 angular-ui-router 내장)을 가질 것입니다.
codef0rmer 2014

1
@ codef0rmer,이 답변을 두 번 이상 찾았습니다. 감사! 이번에도 여전히 훌륭한 답변입니다!
서리가

9

$ routeProvider의 reloadOnSearch 속성을 false로 설정할 수 있습니다.

가능한 중복 질문 : AngularJS에서 컨트롤러를 다시로드하지 않고 경로를 변경할 수 있습니까?

문안 인사


중복 된 것 같습니다. 불행히도 쿼리 변수가 아닌 URL 경로의 일부인 한 동일한 문제가있는 것 같습니다.
Ian Muir

아니요, 중복되지 않습니다.
OZ_

링크 된 질문은 컨트롤러를 다시로드하지 않는 것에 관한 것이고 템플릿을 다시로드하지 않는 것에 관한 것이기 때문에 중복이 아닙니다. 연결된 질문의 솔루션은 뷰를 다시로드합니다.
Lajos Meszaros 2015 년


3

유사한 시나리오를 위해 기본 제공 경로 대신 Angular UI Router를 사용하고 있습니다. 컨트롤러를 다시 인스턴스화하고 전체 뷰를 다시 렌더링하지 않는 것 같습니다.


2
$state.transitionTo()대신 사용해 보셨습니까 $location.path()?
DreamSonic 2013-08-31

1
$ location.path ()를 전혀 변경하지 않습니다. $state.transitionTo()그러면 어디에 써야 합니까?
OZ_

인용구 : "사용자가 위젯을 최대화하면 location.path를 사용하여 URL을 업데이트하지만 이로 인해 뷰가 다시 렌더링됩니다." 경로를 변경하는 대신 $state.transitionTo()URL 해시를 업데이트 할 경로를 호출해야합니다 .
DreamSonic 2013-08-31

아이디어는 두 개의 중첩 된 상태를 가져야한다는 것입니다. 하나는 대시 보드 용이고 다른 하나는 최대화 된 위젯 용입니다. 부모 상태에서 자식 상태로 이동할 때 부모보기가 아닌 자식보기 만 다시 렌더링됩니다.
DreamSonic 2013-08-31

3

나는 이것이 오래된 질문이라는 것을 알고 있지만 답을 찾는 데 하루 반이 걸렸으므로 여기에 있습니다.

angular-ui-router 를 사용하는 경우 경로를 쿼리 문자열로 변환 할 필요가 없습니다 .

현재 버그로 간주 될 수있는 문제로 인해 reloadOnSearch: false상태를 설정 하면 뷰를 다시로드하지 않고도 경로를 변경할 수 있습니다. GitHub 사용자 lmessinger는 데모를 제공 할만큼 친절했습니다. 위에 링크 된 그의 댓글에서 링크를 찾을 수 있습니다.

기본적으로해야 할 일은 다음과 같습니다.

  1. ui-router대신 사용ngRoute
  2. 당신의 주에서 당신이 원하는 것을 선언하십시오 reloadOnSearch: false

내 앱에는 다음과 같은 상태를 사용하여 다른 카테고리로 이동할 수있는 카테고리 목록보기가 있습니다.

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

그게 다야. 도움이 되었기를 바랍니다!


2

구현 방법 :
(주로 하위 부분이 아닌 전체 경로를 변경 해야하는 경우 내 솔루션)

메뉴가있는 페이지 (menuPage)가 있고 탐색시 데이터가 정리되지 않아야합니다 (각 페이지에 많은 입력이 있으며 데이터가 실수로 사라질 경우 사용자는 매우 불만을 갖게됩니다).

  1. $ routeProvider 끄기
  2. mainPage 컨트롤러에서 사용자 지정 지시문 속성이있는 두 개의 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);
    };
    

그게 다야. 각 페이지에 대해 별도의 지시문을 갖는 것은 약간 추악하지만 지시문에서 동적 templateUrl을 (함수로) 사용하면 페이지가 다시 렌더링되고 입력 데이터가 손실됩니다.


0

내가 당신의 질문을 옳게 이해했다면 당신은

  1. 사용자가 / dashboard / : dashboardId에 있고 위젯을 최대화 할 때 위젯을 최대화합니다.
  2. 사용자가 / dashboard / : dashboardId / : maximizedWidgetId로 돌아와서 위젯이 최대화 된 상태로 계속 표시되도록 할 수 있습니다.

routerConfig에서 첫 번째 경로 만 구성하고 RouteParams를 사용할 수 있습니다. PARAM로 전달 된 하나를 극대화 위젯이 구성 경로의 컨트롤러에 전달 매개 변수 경우 식별하고 극대화 할 수 있습니다. 사용자가 처음으로 최대화하는 경우이 최대화 된보기에 대한 URL을 UI의 maximizedWidgetId와 공유합니다.

경로를 업데이트하기 위해 $ location (기본 위치 개체에 대한 래퍼 일뿐)을 사용하는 한보기를 새로 고칩니다.


1
$ location뿐만 아니라보기를 새로 고칩니다. ng-include는 $ location을 변경하지 않아도됩니다.
OZ_

@OZ_ ngInclude는 뷰 내부의 상태 변경 일 뿐이므로 ngInclude를 제안하지 않았습니다. 저는 routeParams
Sivakumar Kailasam

0

사용할 아이디어가 있습니다

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

이렇게하면 다이제스트 사이클이 발생하면 완전히 망가질 것입니다. 그러나 각도가 예상하는 올바른 URL로 다시 설정하면 괜찮습니다. 따라서 이론적으로 앵귤러가 예상하는 올바른 URL을 저장하고 다이제스트가 발생하기 직전에 재설정 할 수 있습니다.

나는 이것을 테스트하지 않았습니다.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.