Sử dụng thành phần từ mô-đun khác


199

Tôi có ứng dụng Angular 2.0.0 được tạo bằng angular-cli.

Khi tôi tạo một thành phần và thêm nó vào AppModulemảng khai báo, tất cả đều tốt, nó hoạt động.

Tôi quyết định tách các thành phần, vì vậy tôi đã tạo một TaskModulevà một thành phần TaskCard. Bây giờ tôi muốn sử dụng TaskCardmột trong các thành phần của AppModule( Boardthành phần).

Ứng dụng:

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 { }

Nhiệm vụ:

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{}

Toàn bộ dự án có sẵn trên https://github.com/evgdim/angular2 (thư mục kanban-board)

Tôi đang thiếu gì? Tôi phải làm gì phải làm để sử dụng TaskCardComponenttrong BoardComponent?

Câu trả lời:


389

Nguyên tắc chính ở đây là:

Các bộ chọn áp dụng trong quá trình biên dịch mẫu thành phần được xác định bởi mô-đun khai báo thành phần đó và đóng cửa tạm thời của xuất khẩu nhập khẩu của mô-đun đó.

Vì vậy, hãy thử xuất nó:

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

Tôi nên xuất khẩu gì?

Xuất các lớp có thể khai báo mà các thành phần trong các mô-đun khác sẽ có thể tham chiếu trong các mẫu của chúng. Đây là những lớp học công cộng của bạn. Nếu bạn không xuất một lớp, nó sẽ ở chế độ riêng tư, chỉ hiển thị với thành phần khác được khai báo trong mô-đun này.

Giây phút bạn tạo một mô-đun mới, lười biếng hay không, bất kỳ mô-đun mới nào và bạn khai báo bất cứ điều gì về nó, mô-đun mới đó có trạng thái sạch (như Ward Bell đã nói trong https://devchat.tv/adv-in-angular/119 -aia-tránh-chung-cạm bẫy-trong-góc2 )

Angular tạo mô-đun bắc cầu cho mỗi @NgModules.

Mô-đun này thu thập các chỉ thị được nhập từ một mô-đun khác (nếu mô-đun bắc cầu của mô-đun nhập khẩu đã xuất chỉ thị) hoặc được khai báo trong mô-đun hiện tại .

Khi biên dịch góc mẫu thuộc về mô-đun, Xnó được sử dụng các chỉ thị đã được thu thập trong 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

nhập mô tả hình ảnh ở đây

Cách này theo hình trên

  • YComponentkhông thể sử dụng ZComponenttrong mẫu của nó vì directivesmảng Transitive module Ykhông chứa ZComponentYModulechưa nhập ZModulemô-đun bắc cầu chứa ZComponenttrong exportedDirectivesmảng.

  • Trong XComponentkhuôn mẫu, chúng ta có thể sử dụng ZComponentTransitive module Xcó mảng chỉ thị chứa ZComponentbởi vì XModulenhập mô-đun ( YModule) mà xuất mô-đun ( ZModule) xuất lệnhZComponent

  • Trong AppComponentmẫu chúng tôi không thể sử dụng XComponentAppModulenhập khẩu XModulenhưng XModulekhông xuất khẩu XComponent.

Xem thêm


13
Làm cách nào để sử dụng "TaskCardComponent" này trong định nghĩa tuyến đường trong mô-đun Nhập?
jackOfAll

17
Thật là một câu trả lời tuyệt vời. Bạn đã tạo ra bản vẽ? Nếu vậy, tôi không nói nên lời. Không phải ai cũng đặt nỗ lực như vậy vào câu trả lời của họ. Cảm ơn bạn
Royi Namir

4
@Royi Vâng, đây là hình ảnh của tôi :) Nó dựa trên mã nguồn từ github.com/angular/angular/blob/master/packages/compiler/src/
Lỗi

@yuruzi, tôi không thể vượt qua nút dom trực tiếp mà không có sự tham khảo stackoverflow.com/questions/47246638/... plnkr.co/edit/DnnjFBa3HLzFKNIdE4q5?p=preview
Karty

@yurzui ... Tôi không hiểu làm thế nào YComponent có thể xuất ZModule, vì tôi thấy đó là một tệp riêng biệt (y.module.ts) và nó không có bất kỳ nhập nào để xuất mô-đun khác (đó là z .module.ts) [hãy hỏi tôi nếu câu hỏi cơ bản của nó]
OmGanesh

42

Bạn phải exporttừ nó NgModule:

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

2
Công việc này, cho đến khi TaskModule được nhập trong AppModule. Nó thất bại khi TaskModule bị lười tải.
Arun

40

(Góc 2 - Góc 7)

Thành phần chỉ có thể được khai báo trong một mô-đun duy nhất. Để sử dụng một thành phần từ một mô-đun khác, bạn cần thực hiện hai tác vụ đơn giản:

  1. Xuất thành phần trong mô-đun khác
  2. Nhập mô-đun khác, vào mô-đun hiện tại

Mô-đun 1:

Có một thành phần (hãy gọi nó là: "Quan trọng"), chúng tôi muốn sử dụng lại trong trang của Mô-đun 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 { }

Mô-đun thứ 2:

Sử dụng lại "Quan trọng", bằng cách nhập 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

Lưu ý rằng để tạo một cái gọi là "mô-đun tính năng", bạn cần nhập CommonModulevào bên trong nó. Vì vậy, mã khởi tạo mô-đun của bạn sẽ trông như thế này:

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 { }

Thêm thông tin có sẵn tại đây: https://angular.io/guide/ngmodule#create-the-feature-module


0

Bất cứ điều gì bạn muốn sử dụng từ một mô-đun khác, chỉ cần đặt nó trong mảng xuất . Như thế này-

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

0

Một cách tiếp cận lớn và tuyệt vời là tải mô-đun từ a NgModuleFactory, bạn có thể tải mô-đun bên trong mô-đun khác bằng cách gọi đây:

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);
    });
}

Tôi đã nhận được điều này từ đây .


NgModuleFactoryLoader hiện không được chấp nhận, vậy cách thay thế tốt nhất của nó để làm điều này là gì?
Muzaffar Mahmood

-2

GIẢI QUYẾT CÁCH SỬ DỤNG MỘT THÀNH PHẦN ĐƯỢC GIẢI QUYẾT TRONG MỘT MODULE TRONG MODULE KHÁC.

Dựa trên lời giải thích của Royi Namir (Cảm ơn bạn rất nhiều). Có một phần còn thiếu để sử dụng lại một thành phần được khai báo trong Mô-đun trong bất kỳ mô-đun nào khác trong khi tải lười biếng được sử dụng.

1: Xuất thành phần trong mô-đun chứa nó:

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

Lần 2: Trong mô-đun nơi bạn muốn sử dụng 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{}

Như thế này, mô-đun thứ hai nhập khẩu mô-đun đầu tiên nhập và xuất thành phần.

Khi chúng ta nhập mô-đun vào mô-đun thứ hai, chúng ta cần xuất lại mô-đun. Bây giờ chúng ta có thể sử dụng thành phần đầu tiên trong mô-đun thứ hai.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.