2016-08-23 24 views
1

저는 Angular 2 (RC5)와 Typescript를 사용하여 SPA를 쓰고 있습니다. 기본 (Bootstrap 4 Alpha 3 사용) 및 맞춤형 사이드 바를 기본 탐색 모음으로 사용합니다. 여기에 그림입니다 : 여기Angular2에서 활성 경로를 기반으로 어떻게 사이드 바를 변경합니까?

enter image description here

의도는 상단 메뉴 바를 사용하여 주 "응용 프로그램"으로 이동하는 것입니다. 현재 나는 Tracker, Proboard 및 Equipment의 세 가지 기본 앱을 매핑했습니다. 메인 애플리케이션이 활성화되면 사이드 바에있는 링크가 변경됩니다. 위의 그림에서 사이드 바에 'Proboard'응용 프로그램에 대한 링크가 표시됩니다.

HTML에서 '* ngIf'선언을 사용하지 않고 활성 경로를 기반으로 사이드 바의 내용을 변경하려면 어떻게해야합니까?

각 앱의 링크를 나열하는 코드 (어쩌면 백엔드 API에서 검색)에 JSON 객체를 갖고 싶습니다. 같은 :

[ 
    { proboard: [ 
    { label: 'Home', link: '/proboard', icon: 'fa-home'}, 
    { label: 'Candidates', link: '/proboard/candidates', icon: 'fa-users'}, 
    { label: 'New', link: '/proboard/candidate/new', icon: 'fa-new-user; } ] 
    }, 
    { tracker: [...] }, 
    { equipment: [...] } 
] 

그런 다음 사용자가 상단 네비게이션 바에서 링크 중 하나를 탐색 것, 사이드 바는 HTML의 NgFor를 사용하여, 위의 배열의 내용으로 채울 수있다.

모든 제안이나 링크를 부탁드립니다.

답변

1

나는 똑같은 짓을 했어. 내가 어떻게 해결했는지.

  1. 그 스트림에 가입 한 서비스를 만든 최상위 응용 프로그램 구성 요소
  2. 에서 메뉴를 생성하고 경로를 변경하는 등록 가능 대상 스트림을 생성 서비스
  3. 에 공통 라우팅 테이블을 유지 메뉴가있는 구성 요소에서
  4. 메뉴가있는 구성 요소에서 선택한 경로를 설정하는 현재 구성 요소에서 subcription.next를 발행하십시오.

다른 유형의 구성 요소 상호 작용으로이를 수행 할 수 있습니다. 여기에 각이 문서에서 해당에 대한 추가 정보를 원하시면입니다 : https://angular.io/docs/ts/latest/cookbook/component-communication.html

+0

'구독 가능한 주제 스트림'을 말하면 관측 가능하다고 말하는 것입니까? 나는 이것이 어떻게 작동하는지 완전히 볼 수 있지만 약간 과장된 느낌이다. –

+0

예, 관찰 가능한 주제 스트림에 대해 이야기하고 있습니다. 물론 이것을 수행하는 방법은 여러 가지가 있습니다. 그것은 내가 생각할 수있는 가장 깨끗한 방법입니다. 당신이하려는 것을 과잉으로 여길 수도 있습니다. –

+0

이것은 실제로이 작업을 실제로 수행 한 방법입니다. –

1

가능한 해결책은 다음과 같습니다.

세 개의 앱은 각각 별도로 정의되어 있으므로 각 앱에서 다시 사용할 수있는 완전히 독립적 인 'SideBarComponent'를 만들 수 있습니다.

@Input() 변수로 원하는 모든 정보를 구성 요소에 제공 할 수 있으므로 필요한 레이블, 링크 및 아이콘 목록을 구성 요소에 제공 할 수 있습니다. 예를 들어

EquipmentComponent.ts

sideBarLinks: any = { proboard: [ 
    { label: 'Home', link: '/proboard', icon: 'fa-home'}, 
    { label: 'Candidates', link: '/proboard/candidates', icon: 'fa-users'}, 
    { label: 'New', link: '/proboard/candidate/new', icon: 'fa-new-user; } ] 
} 

EquipmentComponent.html

<side-bar [buttons]='sideBarLinks'></side-bar> 

SideBarComponent.ts

@Input() 
buttons: any; 

SideBarComponent.html

0
// Use 'buttons' to construct your buttons in the sidebar. Possibly using an ng repeater in this template. 
이 정확히, 나는 이것이 당신이

2. 각도

와 재사용 가능한 구성 요소를 사용하는 방향으로 생각 할텐데 구현 결국하지 않더라도

는 희망이 도움이됩니다!

여기에는 구성 요소 상호 작용에 대해 알아야 할 모든 것 이상의 내용이 있습니다 : https://angular.io/docs/ts/latest/cookbook/component-communication.html.

+0

해야 당신의 main.route를 정의하고이에 대해 생각하는 내 방식에 맞는 그런 것들. 프로그래밍에 익숙하지는 않지만 특히 웹 프로그래밍과 Angular2에 익숙하지 않아서 재사용성에 대해 생각하게되었습니다. –

+1

아, 그렇게 느낍니다. 게임에서 웹 프로그래밍으로 전환하고 같은 종류의 모험을 보았습니다. P Angular code를 재사용 가능하게 만드는 방법에 대한 좋은 자료가 있습니다 (Angular 1.xx 용으로 작성되었지만 Angular 팀에서 권장 한 순서대로). 2와 동일한 디자인 아이디어로 전환) https://www.airpair.com/angularjs/posts/component-based-angularjs-directives https://www.youtube.com/watch?v=UMkd0nYmLzY http://teropa.info/blog/2014/10/24/how-ive-improved-my-angular-apps-by-banning-ng-controller.html 마지막 링크의 동영상은 특히 좋습니다. – Adam

1

2 가지 방법

(1) - 사이드 바 구성 요소에서 변경 사항을 라우터에 가입,하지만 당신은 사용하게됩니다 *ngIf

@Input() 
data: any; 

constructor(private router: Router) { 
    router.changes.subscribe((val) => { 
     if(val === 'noSidebarRoute'){ 
      this.navButtons= false; 
     } 
     else { 
      this.navButtons= navData; 
     } 
    }) 
} 

다음 상위 구성 요소 템플릿

@Component({ 
    selector: 'parent', 
    template: `<side-bar [data]='navData'></side-bar>` 
}); 

export class Parent{ 

navData = [ 
    { proboard: [ 
     { label: 'Home', link: '/proboard', icon: 'fa-home'}, 
     { label: 'Candidates', link: '/proboard/candidates', icon: 'fa-users'}, 
     { label: 'New', link: '/proboard/candidate/new', icon: 'fa-new-user; } 
    ]}, 
    { tracker: [...] }, 
    { equipment: [...] } 
]} 

2 - 앱 구성 요소 (또는 사이드 바 부모 컴포넌트), resolver.resolveComponent을 사용하여 애플리케이션에 사이드 바 구성 요소를 동적으로 추가하십시오. 그러면 데이터 바인딩 (*ngIf)을 사용하지 않게됩니다.

sidebarCmpRef:ComponentRef<any>; 

constructor(private router: Router, 
      private viewContainerRef:ViewContainerRef, 
      private resolver:ComponentResolver) { 

    router.changes.subscribe((val) => { 
     if(val === 'noSidebarRoute'){ 
      if(this.sidebarCmpRef){ 
       this.sidebarCmpRef.destroy(); 
       this.sidebarCmpRef 
      } 
     } 
     else{ 
      this.AddSidebar(); 
     } 
    }) 
} 

AddSidebar(){ 
    if(!this.cmpRef){ 
     this.resolver.resolveComponent(<Type>SideBar) 
      .then((factory:ComponentFactory<any>) => { 
      this.cmpRef = this.viewContainerRef.createComponent(factory); 
      this.cmpRef.instance.buttons= navData; 
     }); 
    } 
} 
+0

흥미 롭습니다. # 1에서 'val'이 활성 경로가됩니까? 'this.show = false' 또는'this를 사용하는 대신에 onder입니다.show = true''this.linkDescriptions = desc'와 같은 것을 할 수 있습니다. 여기서'desc'는 OP에서 언급 한 JSON 배열의 요소입니까? –

+0

실제로'router'에'changes' 속성이 있습니까? 나는 그것을 참조에서 보지 못한다. – estus

+1

@JohnDibling 예 가능합니다. –

1

나는 각도 기본 접근 방식, 즉 경로 내부에서 어린이를로드하는 것을 선호합니다. 자녀/서브 모듈에 다음

import { NgModule } from '@angular/core'; 
import { Routes, RouterModule } from '@angular/router'; 
import { PageNotFoundComponent } from './shared/components/pagenotfound.component'; 

export const appRoutes: Routes = [ 
    { 
    path: 'tracker', 
    loadChildren: 'app/tracker/module#trackermodule', 
    }, 
    { 
    path: 'proboard', 
    loadChildren: 'app/proboard/module#proboard', 
    }, 
{ 
    path: 'equiment', 
    loadChildren: 'app/equiment/module#equiment', 
    }, 
    { 
    path: '**', 
    component: PageNotFoundComponent 
    } 
]; 

@NgModule({ 
    imports: [RouterModule.forRoot(appRoutes)], 
    declarations: [ 
     PageNotFoundComponent 
    ], 
    exports: [RouterModule] 
}) 

export class AppRouterModule { 
} 

을 다음과 같이

라우팅 구성이 좋은 제안입니다

import { RouterModule } from '@angular/router'; 
import { CssComponent } from './view'; 
import { RadioAndCheckBoxComponent } from './radio-and-checkbox/view'; 

export const RouteComponents = [ 
    CssComponent 
]; 

export const Routes = RouterModule.forChild([ 
    { 
    path: '', 
    component: equimentComponent, 
    children: [ 
     { 
     path: 'Home', 
     component: HomeComoponent 
     }, 
     { 
     path: 'Candidates', 
     component: CandidatesComoponent 
     } 
    ] 
    } 
]); 
관련 문제