当前位置: 动力学知识库 > 问答 > 编程问答 >

angular2 - Why does all Angular 2 ng-boostrap Modal code have to be at top in app.module.ts?

问题描述:

Long-time .Net/C#/JavaScript/others coder, just now learning Angular 2. I'm having a hard time keeping ng2-bootstrap Modal code/logic where I think it belongs. In my mind it makes no sense to be forced to import and include all the Modal login code in the top level app.module.ts. I want to move it down into game.module.ts (where it's actually used). However, the only way I can get the Modal to work is if everything is up at the top in app.module.ts.

If you notice anything below that is dumb or bad practice, I'd definitely appreciate it you would point it out. I'm just learning A2 :-)

Here is an example of what does work for me...

// ----------------------------------------------------------------------

// src/app/app.component.ts

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

@Component({

selector: 'app-root',

template: `

<a routerLink="/home">Home</a> |

<a routerLink="/game">Game</a>

<router-outlet></router-outlet>

`

})

export class AppComponent { }

// ----------------------------------------------------------------------

// src/app/app.module.ts

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

import { RouterModule, Routes } from '@angular/router';

import { BrowserModule } from '@angular/platform-browser';

import { FormsModule, ReactiveFormsModule } from '@angular/forms';

import { JsonpModule } from '@angular/http';

import { NgbModule } from '@ng-bootstrap/ng-bootstrap';

import { AppComponent } from './app.component';

import { HomeComponent } from './home.component';

import { GameComponent } from './game.component';

import { PageNotFoundComponent } from './not-found.component';

import { LoginModalComponent, LoginModalContent } from './login-modal.component';

const appRoutes: Routes = [

{ path: '', redirectTo: '/home', pathMatch: 'full' },

{ path: 'home', component: HomeComponent },

{ path: 'game', component: GameComponent },

{ path: '**', component: PageNotFoundComponent }

];

@NgModule({

imports: [

BrowserModule,

FormsModule,

ReactiveFormsModule,

JsonpModule,

NgbModule.forRoot(),

RouterModule.forRoot(appRoutes)

],

declarations: [

AppComponent,

HomeComponent,

GameComponent,

PageNotFoundComponent,

LoginModalComponent,

LoginModalContent

],

bootstrap: [AppComponent],

entryComponents: [LoginModalContent]

})

export class AppModule { }

// ----------------------------------------------------------------------

// src/app/home.component.ts

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

@Component({

selector: 'app-root',

template: `

<div class="container-fluid">

<p>

This is the HOME screen.

</p>

</div>

`

})

export class HomeComponent {

}

@NgModule({

declarations: [

HomeComponent

],

bootstrap: [HomeComponent]

})

export class HomeModule {

}

// ----------------------------------------------------------------------

// src/app/game.component.ts

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

@Component({

selector: 'app-root',

template: `

<template ngbModalContainer></template>

<div class="container-fluid">

<p>

This is the GAME screen.

</p>

<hr>

<login-modal-button></login-modal-button>

</div>

`

})

export class GameComponent {

}

@NgModule({

declarations: [

GameComponent

],

bootstrap: [GameComponent]

})

export class GameModule {

}

// ----------------------------------------------------------------------

// src/app/login-model.component.ts

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

import { NgbModal, NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';

@Component({

selector: 'ngbd-modal-content',

template: `

<div class="modal-header">

<h4 class="modal-title">Hi there! Please login...</h4>

<button type="button" class="close" aria-label="Close" (click)="activeModal.dismiss('Cross click')">

<span aria-hidden="true">&times;</span>

</button>

</div>

<div class="modal-body">

<p>Hello, {{name}}!</p>

</div>

<div class="modal-footer">

<button type="button" class="btn btn-secondary" (click)="activeModal.close('Close click')">Close</button>

</div>

`

})

export class LoginModalContent {

@Input() name;

constructor(public activeModal: NgbActiveModal) { }

}

@Component({

selector: 'login-modal-button',

template: `<button class="btn btn-lg btn-outline-primary" (click)="open()">Open the modal</button>`

})

export class LoginModalComponent {

constructor(private modalService: NgbModal) { }

open() {

const modalRef = this.modalService.open(LoginModalContent);

modalRef.componentInstance.name = 'World';

}

}

Following is how I'm trying to build the app because it makes more sense to me that the Login Modal stuff should be under game.component.ts where it's actually used.

Here is an example of what does NOT work (error at bottom) for me. The only changes are moving the Login Modal pieces out of AppModule down into GameModule...

// ----------------------------------------------------------------------

// src/app/app.module.ts

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

import { RouterModule, Routes } from '@angular/router';

import { BrowserModule } from '@angular/platform-browser';

import { FormsModule, ReactiveFormsModule } from '@angular/forms';

import { JsonpModule } from '@angular/http';

import { NgbModule } from '@ng-bootstrap/ng-bootstrap';

import { AppComponent } from './app.component';

import { HomeComponent } from './home.component';

import { GameComponent } from './game.component';

import { PageNotFoundComponent } from './not-found.component';

const appRoutes: Routes = [

{ path: '', redirectTo: '/home', pathMatch: 'full' },

{ path: 'home', component: HomeComponent },

{ path: 'game', component: GameComponent },

{ path: '**', component: PageNotFoundComponent }

];

@NgModule({

imports: [

BrowserModule,

FormsModule,

ReactiveFormsModule,

JsonpModule,

NgbModule.forRoot(),

RouterModule.forRoot(appRoutes)

],

declarations: [

AppComponent,

HomeComponent,

GameComponent,

PageNotFoundComponent

],

bootstrap: [AppComponent],

})

export class AppModule { }

// ----------------------------------------------------------------------

// src/app/game.component.ts

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

import { LoginModalComponent, LoginModalContent } from './login-modal.component';

@Component({

selector: 'app-root',

template: `

<template ngbModalContainer></template>

<div class="container-fluid">

<p>

This is the GAME screen.

</p>

<hr>

<login-modal-button></login-modal-button>

</div>

`

})

export class GameComponent {

}

@NgModule({

declarations: [

GameComponent,

LoginModalComponent,

LoginModalContent

],

bootstrap: [GameComponent],

entryComponents: [LoginModalContent]

})

export class GameModule {

}

This is the error in Chrome console with above code...

网友答案:

1) Remove GameComponent from declarations array of your AppModule

2) Import GameModule to AppModule

app.module.ts

@NgModule({
    imports: [
        BrowserModule,
        FormsModule,
        ReactiveFormsModule,
        JsonpModule,
        NgbModule.forRoot(),
        RouterModule.forRoot(appRoutes),
        GameModule  // <== this line
    ],
    declarations: [
        AppComponent,
        HomeComponent
    ],
    bootstrap: [AppComponent],
})
export class AppModule { }

3) Import NgbModalModule to GameModule to do ngbModalContainer directive working

game.module.ts

import { NgbModalModule } from '@ng-bootstrap/ng-bootstrap';

@NgModule({
    imports: [NgbModalModule], // <== this line
    declarations: [
        GameComponent,
        LoginModalComponent,
        LoginModalContent
    ],
    bootstrap: [GameComponent],
    entryComponents: [LoginModalContent]
})
export class GameModule {}

I also recommend you to read these two articles:

  • https://angular.io/docs/ts/latest/guide/ngmodule.html
  • https://angular.io/docs/ts/latest/cookbook/ngmodule-faq.html
分享给朋友:
您可能感兴趣的文章:
随机阅读: