HTML52017. 3. 3. 10:48


Crisis 예제에서 "Contact"버튼으로 메세지를 보낼 수 있는 팝업뷰를 띄우려고 한다.

팝업은 앱내에서 다른 페이지전환이 있어도 유지되기를 원한다. 사용자가 명시적으로 닫기전까지는


지금까지는 단일 아웃렛과 차일드아우트까지 사용하는 법에 대해 알아보았다. 라우터는 이름없는 아웃렛은 템플릿내에 하나만 허용한다.

하지만 템플릿은 이름을 부여(네임드아웃렛)하면 여러개의 아웃렛을 사용할 수 있다. 각 명명된 아웃렛은 자신면의 콤포넌트를 갖는 라우트셋을 가질수 있다. 여러개의 아웃렛이 서로다은 라우트를 가지고 동시에 컨텐츠를 표시할 수 있다.


AppComponent에 "popup"이라고 이름 붙인 아웃렛을 추가한다.


src/app/app.component.ts (outlets) <router-outlet></router-outlet> <router-outlet name="popup"></router-outlet>


팝업이 보여질 위치가 된다.


두번째 라우트


명명된 아웃렛은 두번째라우트의 타겟이다.


두번째 라우트도 첫번째 라우트와 유사하다. 몇가지점에서 다른데.

  • 서로 독립적이다.
  • 다른 라우트와 조화된다.
  • 명명된 아웃렛에 표시된다.

ComposeMessageComponent를 src/app/compose-message.component.ts에 추가한다.


아래와 같은 화면이다.



src/app/compose-message.component.ts
import { Component, HostBinding } from '@angular/core';
import { Router }                 from '@angular/router';
import { slideInDownAnimation }   from './animations';
@Component({
  moduleId: module.id,
  templateUrl: './compose-message.component.html',
  styles: [ ':host { position: relative; bottom: 10%; }' ],
  animations: [ slideInDownAnimation ]
})
export class ComposeMessageComponent {
  @HostBinding('@routeAnimation') routeAnimation = true;
  @HostBinding('style.display')   display = 'block';
  @HostBinding('style.position')  position = 'absolute';
  details: string;
  sending: boolean = false;
  constructor(private router: Router) {}
  send() {
    this.sending = true;
    this.details = 'Sending Message...';
    setTimeout(() => {
      this.sending = false;
      this.closePopup();
    }, 1000);
  }
  cancel() {
    this.closePopup();
  }
  closePopup() {
    // Providing a `null` value to the named outlet
    // clears the contents of the named outlet
    this.router.navigate([{ outlets: { popup: null }}]);
  }
}


src/app/compose-message.component.html <h3>Contact Crisis Center</h3> <div *ngIf="details"> {{ details }} </div> <div> <div> <label>Message: </label> </div> <div> <textarea [(ngModel)]="message" rows="10" cols="35" [disabled]="sending"></textarea> </div> </div> <p *ngIf="!sending"> <button (click)="send()">Send</button> <button (click)="cancel()">Cancel</button> </p>


다른 콤포넌트들과 비슷해 보인다. 다른게 두가지가 있는데. send 메서드가 1초동안 대기했다가 팝업을 닫고 있고 closePopup은 "popup"아웃렛을 null로 호출하고 있다.

다른 콤포넌트들과 마찬가지로 AppModule에 declareations에 ComposeMessageComponent를 추가한다.


두번째 라우트 추가


AppRoutingModule에 라우트를 추가한다.

src/app/app-routing.module.ts (compose route)
{
  path: 'compose',
  component: ComposeMessageComponent,
  outlet: 'popup'
},

outlet속성이 추가되었다. ComposeMessageComponent가 popup outlet에 표시될것이다.

html코드내에서는 아래와 같이 호출한다.

src/app/app.component.ts (contact-link) <a [routerLink]="[{ outlets: { popup: ['compose'] } }]">Contact</a>

 compose 라우트가 popup 라우트에 고정되었도 RouterLink디렉티브에 라우트를 지정하기에는 충분하지 않다. 링크파라메터를 지정하고 속성바인딩으로 RouterLink에 바인딩해야 한다.

링크파라메터에는 outlets속성이 객체로 하나 존재하며 popup 아웃렉 속성과 값으로 다른 링크파라메터가  compose 라우트가 지정되어 있다.

이제 사용자가 링크를 클릭하면 compose 라우트가 popup아웃렛에 표시될것이다.


두번째 라우트 네비게이션 : 라우트머징


Crisis Center에서 Contact를 클릭하면 아래와 같은 주소가 찍히는 것을 확인할 수 있다.


http://.../crisis-center(popup:compose)


관심이 쏠리는것이 바로 ... 부분인데.


  • cirsis-center는 첫번째 네비게이션
  • 괄호부분은 두번째 네이게이션
  • 두번째 네비게이션은 popup 아웃랫과 라우트를 의미

 Heros링크를 누르면 이번에 주소가 


http://.../heros(popup:compose)


첫번째주소부분이 변경되었다. 두번째 라우트는 동일하다.

라우터는 첫번째와 두번째 브랜치를 유지한다. 그리고 URL를 표현해준다.

수많은 아웃렉과 라우트를 탑레벨이나 하위레벨로 만들어낼 수 있다. 라우터는 알어서 url을 만들어낸다.


두번째 라우트 정리


아웃렛의 콤포넌트는 새로운 콤포넌트로 이동하기전까지는 계속 유지된다. 두번째 아웃렛도 마찬가지이다. 

모든 두번째 아웃렛은 자체 네비게이션을 가지며 독립적으로 수행된다. 다른 아웃렛의 변경이 영향을 미치지 않는다는 것이다. 그래서 Crisis나 Heroes로 이동해도 Compose는 계속 보여질 수 있는 것이다.

위 예에서 보면 아래와 같이 popup을 제거하는 것을 알 수 있다.


src/app/compose-message.component.ts (closePopup)
closePopup() {
  // Providing a `null` value to the named outlet
  // clears the contents of the named outlet
  this.router.navigate([{ outlets: { popup: null }}]);
}




Posted by 삼스