2017-12-26 9 views
1

簡単に言えば、私はAngular 4アプリを持っています。これにはアンドロイドに触発されたフローティングアクションボタンが含まれています。このボタンをクリックすると、 (ページ内容は基本的に)。私は角度4のルータを使用していますが、違いがあれば、ビューチャイルドのアプローチではいくつかの懸案事項が発生しました。なぜなら、現在アクティブなコンポーネントがいつもわからないからです。可能ならば、単一のテンプレート。アプリコンポーネントから角度4 - 呼び出し子コンポーネントメソッド

私はこれをViewChildデコレータ、ContentChildデコレータ、イベント、サービス、これまで絶対ににしようとしましたが、は機能していました。この時点で私は本当に複雑なのか、それともPEBCAKなのかは分かりません。

問題のボタンがapp.component内に含まれている - ここでの一般的なアイデアがある

<div class="fab-container"> 
    <button class="btn btn-warning btn-fab" (click)="fabAction()"> 
    + 
    </button> 

app.component.ts

@Component({ 
    selector: 'app-root', 
    templateUrl: './app.component.html', 
    styleUrls: ['./app.component.scss'] 
}) 

export class AppComponent { 
    currentUrl: string = null; 

    constructor(private router: Router, private currentRoute: ActivatedRoute) {} 

    ngOnInit() { 
    this.router.events.subscribe((val) => { 
     this.currentUrl = this.router.url; 
    }); 
    } 
} 

app.component.html(簡潔にするためだけのボタン)このボタンがあるときにクリックすると、子コンポーネントのメソッドfabAction()が実行されます。

@Component({ 
    selector: 'app-course-list', 
    templateUrl: './course-list.component.html', 
    styleUrls: ['./course-list.component.scss'] 
}) 
export class CourseListComponent implements OnInit { 

    courses: Course[]; 
    showFilter: boolean = false; 

    constructor(
    private courseService: CourseService 
) { } 

    ngOnInit(): void { 
    this.getCourses(); 
    } 

    getCourses(): void { 
    this.courseService.getCourses().then(courses => this.courses = courses); 
    } 

    // Should execute this method when button is clicked on app component 
    fabAction(): void { 
    console.log('responding to click on parent component'); 
    this.showFilter = !this.showFilter; 
    } 
} 

</div> 

価値は何も各コンポーネントは、それが工場のボタンがアプリのコンポーネント上でクリックされたときに実行する独自のアクションの必要がありますことを、いくつかは、モーダルを開き、他の人がいくつかはそれをリダイレクトする、物事を表示/非表示されますされていないことの一つコンポーネント自体にこの動作を指定できるのは本当にいいですね。

公式の角型文書を読むことで、私は答えよりも多くの質問を残してしまったので、誰かがこれに対処するより理想的な方法を提案できるように、すべてを清潔なスレートに戻しました。

編集は - 要求

<header *ngIf="currentUrl != '/landing'"> 
    <div class="brand"> 
    <img src="/assets/circle-logo.png" /> 
    </div> 
    <nav> 
    <div class="page-title"> 
     <h2>{{ page?.title }}</h2> 
     <h4>{{ page?.strapline }}</h4> 
    </div> 
    <ul class="header-nav"> 
     <li [routerLink]="['/courses']">Courses</li> 
     <li>Dashboard</li> 
     <li>Community</li> 
     <li>Blog</li> 
     <li>About</li> 
    </ul> 
    <div class="fab-container"> 
     <button class="btn btn-warning btn-fab" (click)="fabAction()"> 
     + 
     </button> 
    </div> 
    </nav> 
</header> 
    <router-outlet></router-outlet> 
<app-footer></app-footer> 

としてapp.component.htmlの完全なマークアップはここに私は私のルートを定義私のアプリルーティングモジュールのどの成分がどの経路を表示する(4角度ヒーローのツアーで行われるようデモ)

const routes: Routes = [ 
    { path: '', redirectTo: 'landing', pathMatch: 'full' }, 
    { path: 'landing', component: LandingComponent }, 
    { path: 'courses', component: CourseListComponent }, 
    { path: 'course/:id', component: CourseComponent } 
]; 

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

export class AppRoutingModule {} 
+0

ここでコンポーネントを作成していますか?子コンポーネントをどのように組み込むかを示すコードを投稿することができます –

+0

コンポーネントはルーターアウトレット経由で角度ルータに表示されています。元の投稿に 'app.component.html'のマークアップを追加します – DLMousey

答えて

1

FABを押したときにnextを呼び出すRxJS件名を持つサービスを作成します。それでは、気になるコンポーネントでは、subscribeを対象にすることができます。

import { Subject } from 'rxjs/Subject' 

@Injectable() 
export class FabService { 
    clickSubject = new Subject(); 
} 

app.component

@Component(...) 
export class AppComponent { 

    constructor(private fabService: FabService) {} 

    fabAction() { 
    this.fabService.clickSubject.next(); 
    } 
} 

child.component

@Component(...) 
export class ChildComponent implements OnInit, OnDestroy { 

    private clickSub: Subscription; 

    constructor(private fabService: FabService) {} 

    ngOnInit() { 
    this.clickSub = this.fabService.clickSubject.subscribe(() => { 
     // FAB was clicked 
    }); 
    } 

    ngOnDestroy() { 
    this.clickSub.unsubscribe(); 
    } 
} 

あなたレイジーロード機能モジュール場合、私はこれが動作しない可能性がありますどこ考えることができる唯一の状況は、これらのことから、ありますFabServiceのインスタンスを個別に取得します(または、それを呼び出す最後のインスタンス)。その周りに道があると思うが、頭の上からそれを考えることはできない。

+0

これはまさに私が必要としていたものです。最終的に壁に向かって私の頭を打つのをやめていくことができます:) – DLMousey

1

は、現在のルートに関連するコンポーネントのインスタンスにアクセスするには、共有サービスにこのインスタンスを設定するには、OnActivateイベントフックインターフェースを活用できたときにルートIアクティブ化(S)

@Component({ 
    selector: 'some-cmp', 
    template: ` 
    <div>routerOnActivate: {{log}}</div> 
    `}) 
    export class AppComponent implements OnActivate { 
    constructor(private service:RouteStateService) { 
    } 

    routerOnActivate(next: ComponentInstruction, prev: ComponentInstruction) { 
     this.service.setCurrentRouteComponent(this); 
    } 
} 

次にあなたがこの方法をコンポーネントインスタンスにアクセスし、機能にアクセスできるようになります

var component = this.service.getCurrentRouteComponent(); 
component.somefunction() 

haventは、コードをテストし、詳細はthisに見てください。お役に立てれば。

+0

RouteStateServiceのインポート?角度4または5には表示されません。 –

関連する問題