Gunakan komponen dari modul lain


199

Saya memiliki aplikasi Angular 2.0.0 yang dihasilkan dengan angular-cli.

Ketika saya membuat komponen dan menambahkannya ke AppModuledeklarasi array itu semua baik, itu berfungsi.

Saya memutuskan untuk memisahkan komponen, jadi saya membuat TaskModulekomponen TaskCard. Sekarang saya ingin menggunakan TaskCarddi salah satu komponen AppModule( Boardkomponen).

AppModule:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';

import { AppComponent } from './app.component';
import { BoardComponent } from './board/board.component';
import { LoginComponent } from './login/login.component';

import { MdButtonModule } from '@angular2-material/button';
import { MdInputModule } from '@angular2-material/input';
import { MdToolbarModule } from '@angular2-material/toolbar';

import { routing, appRoutingProviders} from './app.routing';
import { PageNotFoundComponent } from './page-not-found/page-not-found.component';

import { UserService  } from './services/user/user.service';
import { TaskModule } from './task/task.module';


@NgModule({
  declarations: [
    AppComponent,
    BoardComponent,// I want to use TaskCard in this component
    LoginComponent,
    PageNotFoundComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule,
    MdButtonModule,
    MdInputModule,
    MdToolbarModule,
    routing,
    TaskModule // TaskCard is in this module
  ],
  providers: [UserService],
  bootstrap: [AppComponent]
})
export class AppModule { }

TaskModule:

import { NgModule } from '@angular/core';
import { TaskCardComponent } from './task-card/task-card.component';

import { MdCardModule } from '@angular2-material/card';

@NgModule({
  declarations: [TaskCardComponent],
  imports: [MdCardModule],
  providers: []
})
export class TaskModule{}

Seluruh proyek tersedia di https://github.com/evgdim/angular2 (folder kanban-board)

Apa yang saya lewatkan? Apa yang harus saya lakukan untuk digunakan TaskCardComponentdi BoardComponent?

Jawaban:


390

Aturan utama di sini adalah:

Selektor yang berlaku selama kompilasi templat komponen ditentukan oleh modul yang menyatakan komponen itu, dan penutupan transitif dari ekspor impor modul itu.

Jadi, cobalah untuk mengekspornya:

@NgModule({
  declarations: [TaskCardComponent],
  imports: [MdCardModule],
  exports: [TaskCardComponent] <== this line
})
export class TaskModule{}

Apa yang harus saya ekspor?

Ekspor kelas yang dapat dideklarasikan bahwa komponen dalam modul lain harus dapat referensi dalam template mereka. Ini adalah kelas publik Anda. Jika Anda tidak mengekspor kelas, itu tetap pribadi, hanya terlihat oleh komponen lain yang dinyatakan dalam modul ini.

Begitu Anda membuat modul baru, malas atau tidak, modul baru apa pun dan Anda mendeklarasikan apa pun ke dalamnya, modul baru itu memiliki keadaan bersih (seperti yang dikatakan Ward Bell di https://devchat.tv/adv-in-angular/119 -aia-menghindari-perangkap-umum-di-angular2 )

Angular membuat modul transitif untuk masing-masing @NgModules.

Modul ini mengumpulkan arahan yang diimpor dari modul lain (jika modul transitif dari modul yang diimpor telah mengekspor arahan) atau dideklarasikan dalam modul saat ini .

Ketika angular mengkompilasi template yang dimiliki modul X, digunakan arahan-arahan yang telah dikumpulkan dalam X.transitiveModule.directives .

compiledTemplate = new CompiledTemplate(
    false, compMeta.type, compMeta, ngModule, ngModule.transitiveModule.directives);

https://github.com/angular/angular/blob/4.2.x/packages/compiler/src/jit/compiler.ts#L250-L251

masukkan deskripsi gambar di sini

Cara ini sesuai dengan gambar di atas

  • YComponenttidak dapat digunakan ZComponentdalam templatnya karena directivesarray of Transitive module Ytidak mengandung ZComponentkarena YModulebelum mengimpor ZModulemodul transitifnya berisi ZComponentdalam exportedDirectivesarray.

  • Di dalam XComponenttemplat kita dapat menggunakan ZComponentkarena Transitive module Xmemiliki arahan arahan yang berisi ZComponentkarena XModulemodul impor ( YModule) yang mengekspor modul ( ZModule) yang mengekspor arahanZComponent

  • Di dalam AppComponenttemplate kami tidak dapat menggunakan XComponentkarena AppModuleimpor XModuletetapi XModuletidak mengekspor XComponent.

Lihat juga


13
Bagaimana cara menggunakan "TaskCardComponent" ini dalam definisi rute di modul Mengimpor?
jackOfAll

17
Sungguh jawaban yang bagus. Apakah Anda membuat gambar? Jika demikian, saya tidak bisa berkata-kata. Tidak semua orang berupaya seperti itu dalam jawaban mereka. Terima kasih
Royi Namir

4
@Royi Ya, ini gambar saya :) Ini didasarkan pada kode sumber dari github.com/angular/angular/blob/master/packages/compiler/src/…
yurzui

@yuruzi, saya tidak dapat mengirimkan dom dom secara langsung tanpa referensi stackoverflow.com/questions/47246638/… plnkr.co/edit/DnnjFBa3HLzFKNIdE4q5?p=preview
Karty

@ yurzui ... Saya tidak mengerti bagaimana YComponent dapat mengekspor ZModule, karena saya melihat itu sebagai file terpisah (y.module.ts) dan tidak memiliki impor untuk mengekspor modul lain (yaitu z .module.ts) [berikan saya pertanyaan dasar]
OmGanesh

42

Anda harus melakukannya exportdari NgModule:

@NgModule({
  declarations: [TaskCardComponent],
  exports: [TaskCardComponent],
  imports: [MdCardModule],
  providers: []
})
export class TaskModule{}

2
Ini berfungsi, sampai TaskModule diimpor di AppModule. Gagal saat TaskModule sedang lazyloaded.
Arun

40

(Sudut 2 - Sudut 7)

Komponen dapat dideklarasikan dalam satu modul saja. Untuk menggunakan komponen dari modul lain, Anda perlu melakukan dua tugas sederhana:

  1. Ekspor komponen dalam modul lain
  2. Impor modul lainnya, ke modul saat ini

Modul 1:

Memiliki komponen (sebut saja: "ImportantCopmonent"), kami ingin menggunakannya kembali di halaman Modul ke-2.

@NgModule({
declarations: [
    FirstPage,
    ImportantCopmonent // <-- Enable using the component html tag in current module
],
imports: [
  IonicPageModule.forChild(NotImportantPage),
  TranslateModule.forChild(),
],
exports: [
    FirstPage,
    ImportantCopmonent // <--- Enable using the component in other modules
  ]
})
export class FirstPageModule { }

Modul ke-2:

Menggunakan kembali "ImportantCopmonent", dengan mengimpor FirstPageModule

@NgModule({
declarations: [
    SecondPage,
    Example2ndComponent,
    Example3rdComponent
],
imports: [
  IonicPageModule.forChild(SecondPage),
  TranslateModule.forChild(),
  FirstPageModule // <--- this Imports the source module, with its exports
], 
exports: [
    SecondPage,
]
})
export class SecondPageModule { }

2

Perhatikan bahwa untuk membuat apa yang disebut "modul fitur", Anda perlu mengimpor CommonModuledi dalamnya. Jadi, kode inisialisasi modul Anda akan terlihat seperti ini:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

import { TaskCardComponent } from './task-card/task-card.component';
import { MdCardModule } from '@angular2-material/card';

@NgModule({
  imports: [
    CommonModule,
    MdCardModule 
  ],
  declarations: [
    TaskCardComponent
  ],
  exports: [
    TaskCardComponent
  ]
})
export class TaskModule { }

Informasi lebih lanjut tersedia di sini: https://angular.io/guide/ngmodule#create-the-feature-module


0

Apa pun yang ingin Anda gunakan dari modul lain, cukup letakkan di larik ekspor . Seperti ini-

 @NgModule({
  declarations: [TaskCardComponent],
  exports: [TaskCardComponent],
  imports: [MdCardModule]
})

0

Satu pendekatan besar dan hebat adalah memuat modul dari a NgModuleFactory, Anda dapat memuat modul di dalam modul lain dengan memanggil ini:

constructor(private loader: NgModuleFactoryLoader, private injector: Injector) {}

loadModule(path: string) {
    this.loader.load(path).then((moduleFactory: NgModuleFactory<any>) => {
        const entryComponent = (<any>moduleFactory.moduleType).entry;
        const moduleRef = moduleFactory.create(this.injector);
        const compFactory = moduleRef.componentFactoryResolver.resolveComponentFactory(entryComponent);
        this.lazyOutlet.createComponent(compFactory);
    });
}

Saya mendapat ini dari sini .


NgModuleFactoryLoader sudah tidak digunakan lagi sekarang jadi apa cara alternatif terbaik untuk melakukan hal ini?
Muzaffar Mahmood

-2

SOLVED BAGAIMANA CARA MENGGUNAKAN KOMPONEN YANG DEKAT DALAM MODUL DI MODUL LAINNYA.

Berdasarkan penjelasan Royi Namir (Terima kasih banyak). Ada bagian yang hilang untuk menggunakan kembali komponen yang dideklarasikan dalam Modul di modul lain saat pemuatan malas digunakan.

1: Ekspor komponen dalam modul yang berisi itu:

@NgModule({
  declarations: [TaskCardComponent],
  imports: [MdCardModule],
  exports: [TaskCardComponent] <== this line
})
export class TaskModule{}

2nd: Di modul tempat Anda ingin menggunakan TaskCardComponent:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MdCardModule } from '@angular2-material/card';

@NgModule({
  imports: [
   CommonModule,
   MdCardModule
   ],
  providers: [],
  exports:[ MdCardModule ] <== this line
})
export class TaskModule{}

Seperti ini, modul kedua mengimpor modul pertama yang mengimpor dan mengekspor komponen.

Ketika kita mengimpor modul di modul kedua kita perlu mengekspornya lagi. Sekarang kita dapat menggunakan komponen pertama dalam modul kedua.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.