angular 4 tab 표시 줄 전환 을 실현 하 는 방법 예시

관리 시스템 tab 전환 페이지 는 흔히 볼 수 있 는 수요 입 니 다.대략 다음 과 같 습 니 다.

왼쪽 메뉴 를 클릭 하고 오른쪽 에 해당 하 는 옵션 카드 를 표시 한 다음 에 서로 다른 옵션 카드 면 을 동시에 편집 할 수 있 습 니 다.전환 할 때 정 보 를 잃 지 않 습 니 다!
php 또는.net,자바 의 개발 기술 로 디 스 플레이 를 전환 한 다음 ifram 을 추가 하거나 ajax 로 정 보 를 불 러 와 해당 하 는 층 을 표시 합 니 다.
그런데 angular 로 어떻게 이 루어 질 까요?첫 번 째 아 이 디 어 는 같은 ifarm 으로 이 루어 질 수 있 을 까?
두 번 째 로 생각 나 는 건 콘센트 가 이렇게 돼 있어 요.

<router-outlet name="main-content" (activate)="activate($event)" (deactivate)='onDeactivate($event)' ></router-outlet>
하지만 실현 되 지 못 해 간단 한 tab 페이지 를 생각 하 는 것 이 이렇게 어 려 운 가?
아니면 정말 쉬 운 방법 이 없 나 요?
오랫동안 이것 에 관여 하지 않 았 다.
나 는 angular 에 대한 이해 와 학습 이 아직 부족 하 다 는 것 을 알 기 때문에 오랫동안 내 려 놓 았 다.
Angular 경로 재 활용 정책
그래서 한 가지 생각 이 생 겼 습 니 다.반나절 이 걸 려 서 드디어 anguar 4 를 실현 하 였 습 니 다.  tab 전환 페이지 의 대략적인 사고방식 은 다음 과 같다.
1.RouteReuseStrategy 인터페이스 에서 경로 이용 전략 을 사용자 정의 합 니 다.
Simple ReuseStrategy.ts 코드 는 다음 과 같 습 니 다.

import { RouteReuseStrategy, DefaultUrlSerializer, ActivatedRouteSnapshot, DetachedRouteHandle } from '@angular/router';

export class SimpleReuseStrategy implements RouteReuseStrategy {

  public static handlers: { [key: string]: DetachedRouteHandle } = {}

  /**                                     */
  public shouldDetach(route: ActivatedRouteSnapshot): boolean {
    return true;
  }

  /**          。 path  key      &         */
  public store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
    SimpleReuseStrategy.handlers[route.routeConfig.path] = handle
  }

  /**   path                 */
  public shouldAttach(route: ActivatedRouteSnapshot): boolean {
    return !!route.routeConfig && !!SimpleReuseStrategy.handlers[route.routeConfig.path]
  }

  /**         ,     nul */
  public retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
    if (!route.routeConfig) {
      return null
    }
    
    return SimpleReuseStrategy.handlers[route.routeConfig.path]
  }

  /**       ,         */
  public shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
    return future.routeConfig === curr.routeConfig
  }
}

2.모듈 에 정책 등록:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { CommonModule as SystemCommonModule } from '@angular/common';
import { AppComponent } from './app.component';
import { AppRoutingModule,ComponentList } from './app.routing'
import { SimpleReuseStrategy } from './SimpleReuseStrategy';
import { RouteReuseStrategy } from '@angular/router';

@NgModule({
 declarations: [
  AppComponent,
  ComponentList
 ],
 imports: [
  BrowserModule,
  AppRoutingModule,
  FormsModule,
  SystemCommonModule
 ],
 providers: [
  { provide: RouteReuseStrategy, useClass: SimpleReuseStrategy }
 ],
 bootstrap: [AppComponent]
})
export class AppModule { }

위의 두 단 계 는 기본적으로 재 활용 전략 을 실현 하 였 으 나 첫 번 째 효과 도 를 실현 하려 면 다른 일 을 해 야 한다.
3.경로 정의 에 data 데이터 경로 코드 를 추가 하면 다음 과 같 습 니 다.

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { AboutComponent } from './home/about.component'
import { HomeComponent } from './home/home.component'
import { NewsComponent } from './home/news.component'
import { ContactComponent } from './home/contact.component'



export const routes: Routes = [
 { path: '', redirectTo: 'home', pathMatch: 'full', },
 { path: 'home', component: HomeComponent,data: { title: '  ', module: 'home', power: "SHOW" } },
 { path: 'news',component: NewsComponent ,data: { title: '    ', module: 'news', power: "SHOW" }},
 { path: 'contact',component: ContactComponent ,data: { title: '    ', module: 'contact', power: "SHOW" }},
 { path: 'about', component: AboutComponent,data: { title: '    ', module: 'about', power: "SHOW" } },
];

@NgModule({
 imports: [RouterModule.forRoot(routes)],
 exports: [RouterModule]
})

export class AppRoutingModule { }

export const ComponentList=[
  HomeComponent,
  NewsComponent,
  AboutComponent,
  ContactComponent
]

4.component 에서 경로 이벤트 구현  이벤트,app.component 코드 는 다음 과 같 습 니 다.

import { Component } from '@angular/core';
import { SimpleReuseStrategy } from './SimpleReuseStrategy';
import { ActivatedRoute, Router, NavigationEnd } from '@angular/router';
import { Title } from '@angular/platform-browser';
import 'rxjs/add/operator/filter';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/mergeMap';

@Component({
 selector: 'app-root',
 styleUrls:['app.css'],
 templateUrl: 'app.html',
 providers: [SimpleReuseStrategy]
})

export class AppComponent {
 
 //    
 menuList: Array<{ title: string, module: string, power: string,isSelect:boolean }>=[];

 constructor(private router: Router,
  private activatedRoute: ActivatedRoute,
  private titleService: Title) {
 
  //    
  this.router.events.filter(event => event instanceof NavigationEnd)
   .map(() => this.activatedRoute)
   .map(route => {
    while (route.firstChild) route = route.firstChild;
    return route;
   })
   .filter(route => route.outlet === 'primary')
   .mergeMap(route => route.data)
   .subscribe((event) => {
    //  data   
    let title = event['title'];
    this.menuList.forEach(p => p.isSelect=false);
    var menu = { title: title, module: event["module"], power: event["power"], isSelect:true};
    this.titleService.setTitle(title);
    let exitMenu=this.menuList.find(info=>info.title==title);
    if(exitMenu){//       ,      
     this.menuList.forEach(p => p.isSelect=p.title==title);
     return ;
    } 
    this.menuList.push(menu);
   });
 }

 //      
 closeUrl(module:string,isSelect:boolean){
  //           
  let index=this.menuList.findIndex(p=>p.module==module);
  //           
  if(this.menuList.length==1) return ;

  this.menuList=this.menuList.filter(p=>p.module!=module);
  //    
  delete SimpleReuseStrategy.handlers[module];
  if(!isSelect) return;
  //       
  let menu=this.menuList[index-1];
  if(!menu) {//            
    menu=this.menuList[index+1];
  }
  // console.log(menu);
  // console.log(this.menuList);
  this.menuList.forEach(p => p.isSelect=p.module==menu.module );
  //        
  this.router.navigate(['/'+menu.module]);
 }
}
import { Component } from '@angular/core';
import { SimpleReuseStrategy } from './SimpleReuseStrategy';
import { ActivatedRoute, Router, NavigationEnd } from '@angular/router';
import { Title } from '@angular/platform-browser';
import 'rxjs/add/operator/filter';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/mergeMap';

@Component({
 selector: 'app-root',
 styleUrls:['app.css'],
 templateUrl: 'app.html',
 providers: [SimpleReuseStrategy]
})

export class AppComponent {
 
 //    
 menuList: Array<{ title: string, module: string, power: string,isSelect:boolean }>=[];

 constructor(private router: Router,
  private activatedRoute: ActivatedRoute,
  private titleService: Title) {
 
  //    
  this.router.events.filter(event => event instanceof NavigationEnd)
   .map(() => this.activatedRoute)
   .map(route => {
    while (route.firstChild) route = route.firstChild;
    return route;
   })
   .filter(route => route.outlet === 'primary')
   .mergeMap(route => route.data)
   .subscribe((event) => {
    //  data   
    let title = event['title'];
    this.menuList.forEach(p => p.isSelect=false);
    var menu = { title: title, module: event["module"], power: event["power"], isSelect:true};
    this.titleService.setTitle(title);
    let exitMenu=this.menuList.find(info=>info.title==title);
    if(exitMenu){//       ,      
     this.menuList.forEach(p => p.isSelect=p.title==title);
     return ;
    } 
    this.menuList.push(menu);
   });
 }

 //      
 closeUrl(module:string,isSelect:boolean){
  //           
  let index=this.menuList.findIndex(p=>p.module==module);
  //           
  if(this.menuList.length==1) return ;

  this.menuList=this.menuList.filter(p=>p.module!=module);
  //    
  delete SimpleReuseStrategy.handlers[module];
  if(!isSelect) return;
  //       
  let menu=this.menuList[index-1];
  if(!menu) {//            
    menu=this.menuList[index+1];
  }
  // console.log(menu);
  // console.log(this.menuList);
  this.menuList.forEach(p => p.isSelect=p.module==menu.module );
  //        
  this.router.navigate(['/'+menu.module]);
 }
}
app.html 코드 는 다음 과 같 습 니 다.

<div class="row">
 <div class="col-md-4">
  <ul>
   <li><a routerLinkActive="active" routerLink="/home">  </a></li>
   <li><a routerLinkActive="active" routerLink="/about">    </a></li>
   <li><a routerLinkActive="active" routerLink="/news">    </a></li>
   <li><a routerLinkActive="active" routerLink="/contact">    </a></li>
  </ul>
 </div>
 <div class="col-md-8">
  <div class="crumbs clearfix">
   <ul>
     <ng-container *ngFor="let menu of menuList">
       <ng-container *ngIf="menu.isSelect">
         <li class="isSelect">
           <a routerLink="/{{ menu.module }}">{{ menu.title }}</a> 
           <span (click)="closeUrl(menu.module,menu.isSelect)">X</span> 
         </li>
       </ng-container>
       <ng-container *ngIf="!menu.isSelect">
         <li>
           <a routerLink="/{{ menu.module }}">{{ menu.title }}</a> 
           <span (click)="closeUrl(menu.module,menu.isSelect)">X</span> 
         </li>
       </ng-container>
     </ng-container>
   </ul>
  </div>
  <router-outlet></router-outlet>
 </div>
</div>
 전체 효 과 는 다음 과 같다.

최종 적 으로 메뉴 를 클릭 하여 해당 하 는 탭 선택 을 표시 합 니 다.편집 내용 을 전환 할 수 있 습 니 다.탭 을 닫 을 때 메뉴 를 다시 클릭 하면 내용 을 다시 불 러 올 수 있 습 니 다.
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기