source

AngularJS UI 라우터 - 상태를 다시 로드하지 않고 URL 변경

ittop 2023. 3. 23. 23:09
반응형

AngularJS UI 라우터 - 상태를 다시 로드하지 않고 URL 변경

현재 프로젝트에서는 디폴트를 사용하고 있습니다.$routeProvider이 "해크"를 사용해서url페이지를 새로고침하지 않음:

services.service('$locationEx', ['$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;
}]);

및 인controller

$locationEx.skipReload().path("/category/" + $scope.model.id).replace();

교환을 생각하고 있습니다.routeProvider와 함께ui-router네스트 루트의 경우입니다만, 이 정보는ui-router.

가능합니까? - 같은 방법으로angular-ui-router?

이게 왜 필요하죠?예를 들어 설명하겠습니다.
새 카테고리를 만드는 경로는 다음과 같습니다./category/new끝나고clickingSAVE I 쇼에서success-alert루트를 변경하고 싶습니다./category/new로./caterogy/23(23 - db에 저장된 신규 아이템의 ID)

간단히 사용할 수 있습니다. $state.transitionTo 대신 $state.go . $state.go $state.transitionTo 내부적으로만 자동으로 옵션을 설정합니다. { location: true, inherit: true, relative: $state.$current, notify: true } 전화하시면 됩니다. $state.transitionTo 및 세트 notify: false . 예:

$state.go('.detail', {id: newId}) 

대체할 수 있다

$state.transitionTo('.detail', {id: newId}, {
    location: true,
    inherit: true,
    relative: $state.$current,
    notify: false
})

편집: fracz의 제안대로, 다음과 같이 간단하게 할 수 있습니다.

$state.go('.detail', {id: newId}, {notify: false}) 

OK 해결 완료 :) 각도 UI 라우터에는 $urlRouterProvider.deferIntercept()라는 새로운 메서드가 있습니다.https://github.com/angular-ui/ui-router/issues/64

요점은 다음과 같습니다.

angular.module('myApp', [ui.router])
  .config(['$urlRouterProvider', function ($urlRouterProvider) {
    $urlRouterProvider.deferIntercept();
  }])
  // then define the interception
  .run(['$rootScope', '$urlRouter', '$location', '$state', function ($rootScope, $urlRouter, $location, $state) {
    $rootScope.$on('$locationChangeSuccess', function(e, newUrl, oldUrl) {
      // Prevent $urlRouter's default handler from firing
      e.preventDefault();

      /** 
       * provide conditions on when to 
       * sync change in $location.path() with state reload.
       * I use $location and $state as examples, but
       * You can do any logic
       * before syncing OR stop syncing all together.
       */

      if ($state.current.name !== 'main.exampleState' || newUrl === 'http://some.url' || oldUrl !=='https://another.url') {
        // your stuff
        $urlRouter.sync();
      } else {
        // don't sync
      }
    });
    // Configures $urlRouter's listener *after* your custom listener
    $urlRouter.listen();
  }]);

이 메서드는 현재 angular ui 라우터의 마스터 버전에만 포함되어 있다고 생각합니다.옵션 파라미터가 있는 라우터(btw도 좋다)에 포함되어 있습니다.복제하여 소스에서 구축해야 합니다.

grunt build

이 문서는 소스로부터도 액세스 할 수 있습니다.

grunt ngdocs

(/site 디렉토리에 짜넣어져 있습니다).// 상세 정보는 README에서 확인할 수 있습니다.MD

(사용하지 않은) 동적 파라미터를 사용하여 이를 수행하는 다른 방법이 있는같습니다.네이트아벨에 많은 학점이 있다.


다음으로 Angular UI Router의 $stateProvider의 옵션 파라미터를 나타냅니다.이 파라미터는 위와 조합하여 사용했습니다.

angular.module('myApp').config(['$stateProvider', function ($stateProvider) {    

  $stateProvider
    .state('main.doorsList', {
      url: 'doors',
      controller: DoorsListCtrl,
      resolve: DoorsListCtrl.resolve,
      templateUrl: '/modules/doors/doors-list.html'
    })
    .state('main.doorsSingle', {
      url: 'doors/:doorsSingle/:doorsDetail',
      params: {
        // as of today, it was unclear how to define a required parameter (more below)
        doorsSingle: {value: null},
        doorsDetail: {value: null}
      },
      controller: DoorsSingleCtrl,
      resolve: DoorsSingleCtrl.resolve,
      templateUrl: '/modules/doors/doors-single.html'
    });

}]);

이렇게 하면 파라미터 중 하나가 없어져도 상태를 해결할 수 있습니다.SEO는 목적과 가독성이 다릅니다.

위의 예에서는 doorsSingle을 필수 파라미터로 지정했습니다.그것들을 정의하는 방법은 명확하지 않다.다만, 복수의 옵션의 파라메타에서는 정상적으로 동작하기 때문에, 큰 문제는 없습니다.자세한 것은, https://github.com/angular-ui/ui-router/pull/1032#issuecomment-49196090 를 참조해 주세요.

이 문제에 많은 시간을 할애한 후, 내가 얻은 것은 다음과 같다.

$state.go('stateName',params,{
    // prevent the events onStart and onSuccess from firing
    notify:false,
    // prevent reload of the current state
    reload:false, 
    // replace the last record when changing the params so you don't hit the back button and get old params
    location:'replace', 
    // inherit the current params on the url
    inherit:true
});

부르기

$state.go($state.current, {myParam: newValue}, {notify: false});

는 컨트롤러를 새로고침하기 때문에 상태 데이터가 손실됩니다.

이를 회피하려면 파라미터를 dynamic으로 선언하기만 하면 됩니다.

$stateProvider.state({
    name: 'myState',
    url: '/my_state?myParam',
    params: {
        myParam: {
          dynamic: true,    // <----------
        }
    },
    ...
});

그럼 넌 심지어 그 여자랑notify 「 「 」를합니다.

$state.go($state.current, {myParam: newValue})

충분합니다.니토!

매뉴얼에서 다음 항목을 참조하십시오.

dynamictrue파라미터 값을 변경해도 스테이트는 입력 또는 삭제되지 않습니다.해상도는 다시 가져오거나 보기가 다시 로드되지 않습니다.

이는 매개 변수 값이 변경될 때 구성 요소가 자동으로 업데이트되는 UI를 구축하는 데 유용합니다.

이 셋업으로 다음과 같은 문제가 해결되었습니다.

  • 트레이닝 는 URL에서 때 두 번 ..../로로 합니다..../123
  • 다른 상태로 이동할 때 교육 컨트롤러가 다시 호출되지 않습니다.

상태 설정

state('training', {
    abstract: true,
    url: '/training',
    templateUrl: 'partials/training.html',
    controller: 'TrainingController'
}).
state('training.edit', {
    url: '/:trainingId'
}).
state('training.new', {
    url: '/{trainingId}',
    // Optional Parameter
    params: {
        trainingId: null
    }
})

상태 호출(다른 컨트롤러에서)

$scope.editTraining = function (training) {
    $state.go('training.edit', { trainingId: training.id });
};

$scope.newTraining = function () {
    $state.go('training.new', { });
};

트레이닝 컨트롤러

var newTraining;

if (!!!$state.params.trainingId) {

    // new      

    newTraining = // create new training ...

    // Update the URL without reloading the controller
    $state.go('training.edit',
        {
            trainingId : newTraining.id
        },
        {
            location: 'replace', //  update url and replace
            inherit: false,
            notify: false
        });     

} else {

    // edit

    // load existing training ...
}   

url만 변경해야 하며 상태 변경을 방지해야 하는 경우:

위치를 다음과 같이 변경합니다(이력에서 바꾸려면 .replace 추가).

this.$location.path([Your path]).replace();

자신의 상태로 리다이렉트 금지:

$transitions.onBefore({}, function($transition$) {
 if ($transition$.$to().name === '[state name]') {
   return false;
 }
});

이전 버전에서는 다음과 같은 UI 라우터의 v0.2.10을 사용했습니다.

$stateProvider
  .state(
    'home', {
      url: '/home',
      views: {
        '': {
          templateUrl: Url.resolveTemplateUrl('shared/partial/main.html'),
          controller: 'mainCtrl'
        },
      }
    })
  .state('home.login', {
    url: '/login',
    templateUrl: Url.resolveTemplateUrl('authentication/partial/login.html'),
    controller: 'authenticationCtrl'
  })
  .state('home.logout', {
    url: '/logout/:state',
    controller: 'authenticationCtrl'
  })
  .state('home.reservationChart', {
    url: '/reservations/?vw',
    views: {
      '': {
        templateUrl: Url.resolveTemplateUrl('reservationChart/partial/reservationChartContainer.html'),
        controller: 'reservationChartCtrl',
        reloadOnSearch: false
      },
      'viewVoucher@home.reservationChart': {
        templateUrl: Url.resolveTemplateUrl('voucher/partial/viewVoucherContainer.html'),
        controller: 'viewVoucherCtrl',
        reloadOnSearch: false
      },
      'addEditVoucher@home.reservationChart': {
        templateUrl: Url.resolveTemplateUrl('voucher/partial/voucherContainer.html'),
        controller: 'voucherCtrl',
        reloadOnSearch: false
      }
    },
    reloadOnSearch: false
  })

이런 거 해봐

$state.go($state.$current.name, {... $state.params, 'key': newValue}, {notify: false})

Angular 2에서는 RezKesh에서 받아들여진 답변은 다음과 같습니다.

this.uiRouter.stateService.go(
    "home.myRouteState", 
    {
        "param1": this.myParam1,
        "param2": this.myParam2
    },
    { notify: false }
);

다음과 같이 구성 요소의 컨스트럭터에 UIRouter를 주입했다고 가정합니다.

constructor(
    private uiRouter: UIRouter
) { }

ui-router는 전혀 필요 없다고 생각합니다.$location 서비스에 사용할 수 있는 문서에는 첫 번째 단락에 "...$location에 대한 변경 사항이 브라우저 주소 표시줄에 반영됩니다."라고 나와 있습니다.그 후, 다음과 같이 계속된다. "무엇을 계속한다.브라우저의 URL이 변경되어도 페이지 전체가 새로고침되는 일은 없습니다.

이 점을 염두에 두고 단순히 $location을 변경하는 것은 어떨까요?path(메서드가 getter 및 setter인 경우)는 다음과 같습니다.

var newPath = IdFromService;
$location.path(newPath);

문서에서는 경로가 항상 슬래시로 시작되어야 하지만 누락된 경우 이 경로가 추가됩니다.

언급URL : https://stackoverflow.com/questions/23585065/angularjs-ui-router-change-url-without-reloading-state

반응형