programing

구성 요소를 사용하지 않고 angular2 경로에서 외부 URL로 리디렉션하는 방법은 무엇입니까?

skycolor 2023. 7. 31. 21:15
반응형

구성 요소를 사용하지 않고 angular2 경로에서 외부 URL로 리디렉션하는 방법은 무엇입니까?

외부 리디렉션을 만들고 싶지만 모든 경로를 일관되게 하려면 라우터 상태 구성에서 모든 작업(외부 리디렉션 포함)을 수행하면 좋을 것 같습니다.

그래서:

const appRoutes: Routes = [
  {path: '', component: HomeComponent},
  {path: 'first', component: FirstComponent},
  {path: 'second', component: SecondComponent},
  {path: 'external-link', /*would like to have redirect here*/}      
];

UPD: 그리고 는 @koningdavid가 제안한 것과 같은 빈 구성 요소를 이 경우에 사용하고 싶지 않습니다.이 해결책은 저에게 정말 이상하게 보입니다.가상 구성 요소 없이 이러한 경우에 구현하기가 정말 쉬운 것이어야 합니다.

RedirectGuard를 생성할 수 있습니다.

import {Injectable} from '@angular/core';
import {CanActivate, ActivatedRouteSnapshot, Router, RouterStateSnapshot} from '@angular/router';

@Injectable({
    providedIn: 'root'
})
export class RedirectGuard implements CanActivate {

  constructor(private router: Router) {}

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {

      window.location.href = route.data['externalUrl'];
      return true;

  }
}

app.module로 가져오기:

providers: [RedirectGuard],

경로를 정의합니다.

{
     path: 'youtube',
     canActivate: [RedirectGuard],
     component: RedirectGuard,
     data: {
       externalUrl: 'https://www.youtube.com/'
     }
 }

경로의 해결 옵션을 사용하여 트릭으로 원하는 것을 달성할 수 있습니다.해결은 초기화할 경로에 대해 Angular2가 얻는 일부 데이터 값입니다.자세한 내용은 공식 문서에서 확인할 수 있습니다.

저는 이 접근법을 시도해 보았는데 효과가 있습니다.예:

공급자 섹션에 추가(및 라우팅에서 필요한 클래스 가져오기)

@NgModule({
    providers: [
        {
            provide: 'externalUrlRedirectResolver',
            useValue: (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) =>
            {
                window.location.href = (route.data as any).externalUrl;
            }
        }
    ]
})

그런 다음 경로를 다음과 같이 정의할 수 있습니다.

{
        path: 'test',
        component: AnyRandomComponent,
        resolve: {
            url: 'externalUrlRedirectResolver'
        },
        data: {
            externalUrl: 'http://www.google.com'
        }
    }

외부 URL로 리디렉션됩니다.정말로 좀 진부한 방법입니다.구성 요소를 전혀 사용하지 않고 결과를 얻으려고 했지만, 당신은 어느 하나를 사용해야 합니다.redirectTo또는component또는children또는loadChildren.redirectTo실험은 할 수 있지만 아이들에 대해서는 확신할 수 없습니다.

공급자의 직접적인 기능이 아닌 멋진 클래스에서 구현할 수 있습니다.자세한 내용은 설명서에 나와 있습니다(위 참조.

추신: 저는 차라리 리디렉션 구성 요소를 직접 사용하고 싶습니다.데이터와 라우터에서 상태를 가져오는 트릭을 사용하면 됩니다.externalUrl매개 변수로 사용할 수 있습니다.

NG2 라우터는 외부 리다이렉트를 지원하지 않는 것으로 알고 있습니다.해결 방법으로 리디렉션 구성 요소를 생성할 수 있습니다.

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'redirect',
  template: 'redirecting...'
})
export class RedirectComponent implements OnInit {
  constructor() { }

  ngOnInit() {
    window.location.href = 'http://www.redirecturl.com'
  }
}

그리고 그것을 당신의 라우팅에 사용합니다.

{ path: 'login', component: RedirectComponent, pathmath: 'full'},

음...

ng2 Router에 전화하지 말고 URL만 요청하시면 될 것 같습니다...


예를 들면...

<a href="http://example.com">External</a>

대신에

<a routerLink="/someRoute" routerLinkActive="active">External</a>

OR

window.location.href = 'http://www.example.com'

대신에

this.router.navigate( [ '/someRoute', 'someParam' ] );

그렇죠...?

그냥 사용:

{
    path: 'external-link',
    loadChildren: () => new Promise( () => { if(window.location.href.match(/external-link/) ) window.location.href = 'https://external-link.com/'; } ) 
  },

라우터가 외부로 리디렉션할 수 없습니다.외부 리소스는 앱의 상태일 수 없습니다.

모든 경로를 한 지점에서 볼 수 있도록 하기 위해 경로와 동일한 파일에 모든 외부 경로를 포함하는 다른 상수 배열을 정의할 수 있습니다.

Navigation End 이벤트를 사용할 수 있습니다.

'@angular/router'에서 {NavigationEnd,Router} 가져오기;

app.component.ts

this.router.events.subscribe(event => {
  if (event instanceof NavigationEnd) {
    if (event.url.includes('faq')) {
      // open in the same tab:
      window.location.href = 'https://faq.website.com';

      // open a new tab:
      // window.open('https://faq.website.com', '_blank');

      // and redirect the current page:
      // this.router.navigate(['/']);
    }
  }
});

추신: 앱 라우팅 모듈에서 경로를 제거하는 것을 잊지 마십시오.

모든 URL에 대한 구성 요소를 생성하고 싶지 않은 것 같습니다. 그래서 구성 요소 없이 구성 요소를 생성하려고 하는 것입니다.

따라서 구성 요소 개체를 생성하는 함수를 만들어 보십시오.

예를 들면...

function generateLinkingComponent( url ) {
  // Generate your component using koningdavid's code
  // replace 'http://www.redirecturl.com' with url param
  // and return it...
}

라우터 구성에 이와 같이 추가합니다.

const appRoutes: Routes = [
  {path: '', component: HomeComponent},
  {path: 'first', component: FirstComponent},
  {path: 'second', component: SecondComponent},
  {path: 'external-link', component: generateLinkingComponent( 'http://example.com' )},
  {path: 'client-login', component: generateLinkingComponent( 'http://client-login.example.com' )},
  {path: 'admin-login', component: generateLinkingComponent( 'http://admin.example.com' )},
];

JS를 사용하면 쉽겠지만... typeScript 함수의 클래스를 반환하는 방법은 잘 모르겠습니다...

그게 도움이 되길...

일리야의 답변을 마무리합니다.

이 모듈을 추가합니다.

import { Component, Injectable, NgModule } from '@angular/core';
import { ActivatedRouteSnapshot, Resolve } from '@angular/router';

@Component({
  template: ''
})
class ExternalLinkComponent {
  constructor() {
  }
}

@Injectable()
class ExternalLinkResolver implements Resolve<any> {
  resolve(route: ActivatedRouteSnapshot): any {
    window.location.href = route.data.targetUri;
    return true;
  }
}

export class ExternalRoute {
  data: {
    targetUri: string;
  };
  path: string;
  pathMatch = 'full';
  resolve = { link: ExternalLinkResolver };
  component = ExternalLinkComponent;

  constructor(path: string, targetUri: string) {
    this.path = path;
    this.data = { targetUri: targetUri };
  }

}

@NgModule({
  providers: [ ExternalLinkResolver ],
  declarations: [ExternalLinkComponent]
})
export class ExternalRoutesModule { }

그런 다음 가져오기ExternalRoutesModuleExternalRoute 인스턴스를 추가합니다.

const childRoutes: Routes = [
  new ExternalRoute('', '/settings/account'),
  { path: 'staff-profiles', component:  StaffProfilesComponent},
  { path: 'staff-assignments', component:  StaffAssignmentsComponent}
];

const routes: Routes = [
  { path: '', component: BaseComponent, children: childRoutes }
];

@NgModule({
  imports: [ ExternalRoutesModule, RouterModule.forChild(routes) ],
  exports: [ RouterModule ]
})
export class SettingsRoutingModule { }

참고 이 예에서는 loadChildren을 통해 하위 모듈 경로를 마운트하고 있습니다.

여기 많은 문제 없이 작동해야 하는 코드가 있습니다.참고로 라우터 이벤트 오류 처리기는 구성 요소의 위치에 관계없이 아무 곳에나 배치할 수 있습니다.

app.component.vmdk

Angular Port is in 4200
<a routerLink="/test">Main Link - 1</a> |

<a [routerLink]="getLinkWithExternal({url: '/test', external:false})">Other Link - 1a</a> |
<a [routerLink]="getLinkWithExternal({url: 'http://localhost:4211', external:true})">Other Link - 1b</a> |

<a [routerLink]="getLink({url: '/test'})">Other Link - 1a</a> |
<a [routerLink]="getLink({url: 'http://localhost:4211'})">Other Link - 1b</a> |


<a style="cursor: pointer; text-decoration: underline;" (click)="routeLink('/test')">Other Link - 1c</a> |
<a style="cursor: pointer; text-decoration: underline;" (click)="routeLink('http://localhost:4211')">Other Link - 1d</a>

<router-outlet></router-outlet>

app.component.ts

import { Component } from '@angular/core';
import { NavigationEnd, Router } from '@angular/router';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'app';

  constructor(private router: Router) { }

  // RECOMMENDATION - Add following in menus of each microservice (individual and different)
  //    external: true
  // Will make it a better menu structure for each microservice
  // If Single and same menu for all microservices then remove external === true
  // Logic One
  getLinkWithExternal(sidebarnavLink: any) {
    this.router.errorHandler = function (error: any) {
      if (!sidebarnavLink.url.includes(window.location.origin.toString()) && sidebarnavLink.url.includes("http") && sidebarnavLink.external === true) {
        window.location.href = sidebarnavLink.url.toString();
        return true;
      }
      return null;
    }.bind(sidebarnavLink);
    return [sidebarnavLink.url];
  }

  getLinkWithExternalWithEventSubscribe(sidebarnavLink: any) {
    this.router.events.subscribe(function (event) {
      if (event instanceof NavigationEnd) {
        if (event.url.includes('http')) {
          if (!sidebarnavLink.url.includes(window.location.origin.toString()) && sidebarnavLink.url.includes("http") && sidebarnavLink.external === true) {
            window.location.href = sidebarnavLink.url.toString();
            return true;
          }
          return this.router.navigateByUrl(sidebarnavLink.url);
          // return this.router.navigate([sidebarnavLink.url]);
        }
        return this.router.navigateByUrl(sidebarnavLink.url);
        // return this.router.navigate([sidebarnavLink.url]);
      }
    }.bind(sidebarnavLink))
  }

  getLinkWithExternalImplementationTwoWithNoRouteError(sidebarnavLink: any) {
    if (!sidebarnavLink.url.includes(window.location.origin.toString()) && sidebarnavLink.url.includes("http") && sidebarnavLink.external === true) {
      window.location.href = sidebarnavLink.url.toString();
      return true;
    }
    return [sidebarnavLink.url];
  }

  // Logic Two
  getLink(sidebarnavLink: any) {
    this.router.errorHandler = function (error: any) {
      if (!sidebarnavLink.url.includes(window.location.origin.toString()) && sidebarnavLink.url.includes("http")) {
        window.location.href = sidebarnavLink.url.toString();
        return true;
      }
      return null;
    }.bind(sidebarnavLink);
    return [sidebarnavLink.url];
  }

  // Logic Three
  routeLink(lnk: any) {
    if (lnk.includes("http")) {
      console.log("Test");
      window.location.href = lnk;
      return true;
    }
    return this.router.navigateByUrl(lnk);
    // return this.router.navigate([lnk]);
  }

}

언급URL : https://stackoverflow.com/questions/40150393/how-to-redirect-to-an-external-url-from-angular2-route-without-using-component

반응형