国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

[譯] 別再對 Angular Modules 感到迷惑

LMou / 2452人閱讀

摘要:大多數初學者會認為也有封裝規則,但實際上沒有。第二個規則是最后導入模塊的,會覆蓋前面導入模塊的。

原文鏈接:Avoiding common confusions with modules in Angular

Angular Modules 是個相當復雜的話題,甚至 Angular 開發團隊在官網上寫了好幾篇有關 NgModule 的文章教程。這些教程清晰的闡述了 Modules 的大部分內容,但是仍欠缺一些內容,導致很多開發者被誤導。我看到很多開發者由于不知道 Modules 內部是如何工作的,所以經常理解錯相關概念,使用 Modules API 的姿勢也不正確。

本文將深度解釋 Modules 內部工作原理,爭取幫你消除一些常見的誤解,而這些錯誤我在 StackOverflow 上經常看到有人提問。

模塊封裝

Angular 引入了模塊封裝的概念,這個和 ES 模塊概念很類似(注:ES Modules 概念可以查看 TypeScript 中文網的 Modules),基本意思是所有聲明類型,包括組件、指令和管道,只可以在當前模塊內部,被其他聲明的組件使用。比如,如果我在 App 組件中使用 A 模塊的 a-comp 組件:

@Component({
  selector: "my-app",
  template: `
      

Hello {{name}}

` }) export class AppComponent { }

Angular 編譯器就會拋出錯誤:

Template parse errors: "a-comp" is not a known element

這是因為 App 模塊中沒有申明 a-comp 組件,如果我想要使用這個組件,就不得不導入 A 模塊,就像這樣:

@NgModule({
  imports: [..., AModule]
})
export class AppModule { }

上面描述的就是 模塊封裝。不僅如此,如果想要 a-comp 組件正常工作,得設置它為可以公開訪問,即在 A 模塊的 exports 屬性中導出這個組件:

@NgModule({
  ...
  declarations: [AComponent],
  exports: [AComponent]
})
export class AModule { }

同理,對于指令和管道,也得遵守 模塊封裝 的規則:

@NgModule({
  ...
  declarations: [
    PublicPipe, 
    PrivatePipe, 
    PublicDirective, 
    PrivateDirective
  ],
  exports: [PublicPipe, PublicDirective]
})
export class AModule {}

需要注意的是,模塊封裝 原則不適用于在 entryComponents 屬性中注冊的組件,如果你在使用動態視圖時,像 譯 關于 Angular 動態組件你需要知道的 這篇文章中所描述的方式去實例化動態組件,就不需要在 A 模塊的 exports 屬性中去導出 a-comp 組件。當然,還得導入 A 模塊。

大多數初學者會認為 providers 也有封裝規則,但實際上沒有。在 非懶加載模塊 中申明的任何 provider 都可以在程序內的任何地方被訪問,下文將會詳細解釋原因。

模塊層級

初學者最大的一個誤解就是認為,一個模塊導入其他模塊后會形成一個模塊層級,認為該模塊會成為這些被導入模塊的父模塊,從而形成一個類似模塊樹的層級,當然這么想也很合理。但實際上,不存在這樣的模塊層級。因為 所有模塊在編譯階段會被合并,所以導入和被導入模塊之間不存在任何層級關系。

就像 組件 一樣,Angular 編譯器也會為根模塊生成一個模塊工廠,根模塊就是你在 main.ts 中,以參數傳入 bootstrapModule() 方法的模塊:

platformBrowserDynamic().bootstrapModule(AppModule);

Angular 編譯器使用 createNgModuleFactory 方法來創建該模塊工廠(注:可參考 L274 -> L60 -> L109 -> L153-L155 -> L50),該方法需要幾個參數(注:為清晰理解,不翻譯。最新版本不包括第三個依賴參數。):

module class reference

bootstrap components

component factory resolver with entry components

definition factory with merged module providers

最后兩點解釋了為何 providersentry components 沒有模塊封裝規則,因為編譯結束后沒有多個模塊,而僅僅只有一個合并后的模塊。并且在編譯階段,編譯器不知道你將如何使用 providers 和動態組件,所以編譯器去控制封裝。但是在編譯階段的組件模板解析過程時,編譯器知道你是如何使用組件、指令和管道的,所以編譯器能控制它們的私有申明。(注:providersentry components 是整個程序中的動態部分 dynamic content,Angular 編譯器不知道它會被如何使用,但是模板中寫的組件、指令和管道,是靜態部分 static content,Angular 編譯器在編譯的時候知道它是如何被使用的。這點對理解 Angular 內部工作原理還是比較重要的。)

讓我們看一個生成模塊工廠的示例,假設你有 AB 兩個模塊,并且每一個模塊都定義了一個 provider 和一個 entry component

@NgModule({
  providers: [{provide: "a", useValue: "a"}],
  declarations: [AComponent],
  entryComponents: [AComponent]
})
export class AModule {}

@NgModule({
  providers: [{provide: "b", useValue: "b"}],
  declarations: [BComponent],
  entryComponents: [BComponent]
})
export class BModule {}

根模塊 App 也定義了一個 provider 和根組件 app,并導入 AB 模塊:

@NgModule({
  imports: [AModule, BModule],
  declarations: [AppComponent],
  providers: [{provide: "root", useValue: "root"}],
  bootstrap: [AppComponent]
})
export class AppModule {}

當編譯器編譯 App 根模塊生成模塊工廠時,編譯器會 合并 所有模塊的 providers,并只為合并后的模塊創建模塊工廠,下面代碼展示模塊工廠是如何生成的:

createNgModuleFactory(
    // reference to the AppModule class
    AppModule,

    // reference to the AppComponent that is used
    // to bootstrap the application
    [AppComponent],

    // module definition with merged providers
    moduleDef([
        ...

        // reference to component factory resolver
        // with the merged entry components
        moduleProvideDef(512, jit_ComponentFactoryResolver_5, ..., [
            ComponentFactory_,
            ComponentFactory_,
            ComponentFactory_
        ])

        // references to the merged module classes 
        // and their providers
        moduleProvideDef(512, AModule, AModule, []),
        moduleProvideDef(512, BModule, BModule, []),
        moduleProvideDef(512, AppModule, AppModule, []),
        moduleProvideDef(256, "a", "a", []),
        moduleProvideDef(256, "b", "b", []),
        moduleProvideDef(256, "root", "root", [])
]);

從上面代碼知道,所有模塊的 providersentry components 都將會被合并,并傳給 moduleDef() 方法,所以無論導入多少個模塊,編譯器只會合并模塊,并只生成一個模塊工廠。該模塊工廠會使用模塊注入器來生成合并模塊對象(注:查看 L232),然而由于只有一個合并模塊,Angular 將只會使用這些 providers,來生成一個單例的根注入器。

現在你可能想到,如果兩個模塊里定義了相同的 provider token,會發生什么?

第一個規則 則是導入其他模塊的模塊中定義的 provider 總是優先勝出,比如在 AppModule 中也同樣定義一個 a provider

@NgModule({
  ...
  providers: [{provide: "a", useValue: "root"}],
})
export class AppModule {}

查看生成的模塊工廠代碼:

moduleDef([
     ...
     moduleProvideDef(256, "a", "root", []),
     moduleProvideDef(256, "b", "b", []),
 ]);

可以看到最后合并模塊工廠包含 moduleProvideDef(256, "a", "root", []),會覆蓋 AModule 中定義的 {provide: "a", useValue: "a"}

第二個規則 是最后導入模塊的 providers,會覆蓋前面導入模塊的 providers。同樣,也在 BModule 中定義一個 a provider

@NgModule({
  ...
  providers: [{provide: "a", useValue: "b"}],
})
export class BModule {}

然后按照如下順序在 AppModule 中導入 AModuleBModule

@NgModule({
  imports: [AModule, BModule],
  ...
})
export class AppModule {}

查看生成的模塊工廠代碼:

moduleDef([
     ...
     moduleProvideDef(256, "a", "b", []),
     moduleProvideDef(256, "root", "root", []),
 ]);

所以上面代碼已經驗證了第二條規則。我們在 BModule 中定義了 {provide: "a", useValue: "b"},現在讓我們交換模塊導入順序:

@NgModule({
  imports: [BModule, AModule],
  ...
})
export class AppModule {}

查看生成的模塊工廠代碼:

moduleDef([
     ...
     moduleProvideDef(256, "a", "a", []),
     moduleProvideDef(256, "root", "root", []),
 ]);

和預想一樣,由于交換了模塊導入順序,現在 AModule{provide: "a", useValue: "a"} 覆蓋了 BModule{provide: "a", useValue: "b"}

注:上文作者提供了 AppModule 被 @angular/compiler 編譯后的代碼,并針對編譯后的代碼分析多個 modules 的 providers 會被合并。實際上,我們可以通過命令 yarn ngc -p ./tmp/tsconfig.json 自己去編譯一個小實例看看,其中,./node_modules/.bin/ngc@angular/compiler-cli 提供的 cli 命令。我們可以使用 ng new module 新建一個項目,我的版本是 6.0.5。然后在項目根目錄創建 /tmp 文件夾,然后加上 tsconfig.json,內容復制項目根目錄的 tsconfig.json,然后加上一個 module.ts 文件。module.ts 內容包含根模塊 AppModule,和兩個模塊 AModuleBModuleAModule 提供 AService{provide:"a", value:"a"}{provide:"b", value:"b"} 服務,而 BModule 提供 BService{provide: "b", useValue: "c"}AModuleBModule 按照先后順序導入根模塊 AppModule,完整代碼如下:
import {Component, Inject, Input, NgModule} from "@angular/core";
import "./goog"; // goog.d.ts 源碼文件拷貝到 /tmp 文件夾下
import "hammerjs";
import {platformBrowserDynamic} from "@angular/platform-browser-dynamic";
export class AService {
}
@NgModule({
  providers: [
    AService,
    {provide: "a", useValue: "a"},
    {provide: "b", useValue: "b"},
  ],
})
export class AModule {
}
export class BService {
}
@NgModule({
  providers: [
    BService,
    {provide: "b", useValue: "c"}
  ]
})
export class BModule {
}
@Component({
  selector: "app",
  template: `
    

{{name}}

` }) export class AppComp { name = "lx1036"; } export class AppService { } @NgModule({ imports: [AModule, BModule], declarations: [AppComp], providers: [ AppService, {provide: "a", useValue: "b"} ], bootstrap: [AppComp] }) export class AppModule { } platformBrowserDynamic().bootstrapModule(AppModule).then(ngModuleRef => console.log(ngModuleRef));
然后 yarn ngc -p ./tmp/tsconfig.json 使用 @angular/compiler 編譯這個 module.ts 文件會生成多個文件,包括 module.jsmodule.factory.js
先看下 module.jsAppModule 類會被編譯為如下代碼,發現我們在 @NgModule 類裝飾器中寫的元數據,會被賦值給 AppModule.decorators 屬性,如果是屬性裝飾器,會被賦值給 propDecorators 屬性:
var AppModule = /** @class */ (function () {
    function AppModule() {
    }
    AppModule.decorators = [
        { type: core_1.NgModule, args: [{
                    imports: [AModule, BModule],
                    declarations: [AppComp],
                    providers: [
                        AppService,
                        { provide: "a", useValue: "b" }
                    ],
                    bootstrap: [AppComp]
                },] },
    ];
    return AppModule;
}());
exports.AppModule = AppModule;
然后看下 module.factory.js 文件,這個文件很重要,本文關于模塊 providers 合并就可以從這個文件看出。該文件 AppModuleNgFactory 對象中就包含合并后的 providers,這些 providers 來自于 AppModule,AModule,BModule,并且 AppModule 中的 providers 會覆蓋其他模塊的 providersBModule 中的 providers 會覆蓋 AModuleproviders,因為 BModuleAModule 之后導入,可以交換導入順序看看發生什么。其中,?cmf 是 createNgModuleFactory,?mod 是 moduleDef,?mpd 是 moduleProvideDefmoduleProvideDef 第一個參數是 enum NodeFlags 節點類型,用來表示當前節點是什么類型,比如 i0.?mpd(256, "a", "a", []) 中的 256 表示 TypeValueProvider 是個值類型。
Object.defineProperty(exports, "__esModule", { value: true });
var i0 = require("@angular/core");
var i1 = require("./module");

var AModuleNgFactory = i0.?cmf(
  i1.AModule,
  [],
  function (_l) {
    return i0.?mod([
      i0.?mpd(512, i0.ComponentFactoryResolver, i0.?CodegenComponentFactoryResolver, [[8, []], [3, i0.ComponentFactoryResolver], i0.NgModuleRef]),
      i0.?mpd(4608, i1.AService, i1.AService, []),
      i0.?mpd(1073742336, i1.AModule, i1.AModule, []),
      i0.?mpd(256, "a", "a", []),
      i0.?mpd(256, "b", "b", [])]
    );
  });
exports.AModuleNgFactory = AModuleNgFactory;

var BModuleNgFactory = i0.?cmf(
  i1.BModule,
  [],
  function (_l) {
    return i0.?mod([
      i0.?mpd(512, i0.ComponentFactoryResolver, i0.?CodegenComponentFactoryResolver, [[8, []], [3, i0.ComponentFactoryResolver], i0.NgModuleRef]),
      i0.?mpd(4608, i1.BService, i1.BService, []),
      i0.?mpd(1073742336, i1.BModule, i1.BModule, []),
      i0.?mpd(256, "b", "c", [])
    ]);
  });
exports.BModuleNgFactory = BModuleNgFactory;

var AppModuleNgFactory = i0.?cmf(
  i1.AppModule,
  [i1.AppComp], // AppModule 的 bootstrapComponnets 啟動組件數據
  function (_l) {
    return i0.?mod([
      i0.?mpd(512, i0.ComponentFactoryResolver, i0.?CodegenComponentFactoryResolver, [[8, [AppCompNgFactory]], [3, i0.ComponentFactoryResolver], i0.NgModuleRef]),
      i0.?mpd(4608, i1.AService, i1.AService, []),
      i0.?mpd(4608, i1.BService, i1.BService, []),
      i0.?mpd(4608, i1.AppService, i1.AppService, []),
      i0.?mpd(1073742336, i1.AModule, i1.AModule, []),
      i0.?mpd(1073742336, i1.BModule, i1.BModule, []),
      i0.?mpd(1073742336, i1.AppModule, i1.AppModule, []),
      i0.?mpd(256, "a", "b", []),
      i0.?mpd(256, "b", "c", [])]);
  });
exports.AppModuleNgFactory = AppModuleNgFactory;
自己去編譯實踐下,會比只看文章的解釋,效率更高很多。
懶加載模塊

現在又有一個令人困惑的地方-懶加載模塊。官方文檔是這樣說的(注:不翻譯):

Angular creates a lazy-loaded module with its own injector, a?child?of the root injector… So a lazy-loaded module that imports that shared module makes its own copy of the service.

所以我們知道 Angular 會為懶加載模塊創建它自己的注入器,這是因為 Angular 編譯器會為每一個懶加載模塊編譯生成一個 獨立的組件工廠。這樣在該懶加載模塊中定義的 providers 不會被合并到主模塊的注入器內,所以如果懶加載模塊中定義了與主模塊有著相同的 provider,則 Angular 編譯器會為該 provider 創建一份新的服務對象。

所以懶加載模塊也會創建一個層級,但是注入器的層級,而不是模塊層級。 在懶加載模塊中,導入的所有模塊同樣會在編譯階段被合并為一個,就和上文非懶加載模塊一樣。

以上相關邏輯是在 @angular/router 包的 RouterConfigLoader 代碼里,該段展示了如何加載模塊和創建注入器:

export class RouterConfigLoader {

  load(parentInjector, route) {
    ...
    const moduleFactory$ = this.loadModuleFactory(route.loadChildren);
    return moduleFactory$.pipe(map((factory: NgModuleFactory) => {
          ...

          const module = factory.create(parentInjector);
        ...
     }));
  }

  private loadModuleFactory(loadChildren) {
    ...
    return this.loader.load(loadChildren)
  }
}

查看這行代碼:

const module = factory.create(parentInjector);

傳入父注入器來創建懶加載模塊新對象。

forRoot 和 forChild 靜態方法

查看官網是如何介紹的(注:不翻譯):

Add a CoreModule.forRoot?method that configures the core?UserService… Call?forRoot?only in the root application module,?AppModule

這個建議是合理的,但是如果你不理解為什么這樣做,最終會寫出類似下面代碼:

@NgModule({
  imports: [
    SomeLibCarouselModule.forRoot(),
    SomeLibCheckboxModule.forRoot(),
    SomeLibCloseModule.forRoot(),
    SomeLibCollapseModule.forRoot(),
    SomeLibDatetimeModule.forRoot(),
    ...
  ]
})
export class SomeLibRootModule {...}

每一個導入的模塊(如 CarouselModuleCheckboxModule 等等)不再定義任何 providers,但是我覺得沒理由在這里使用 forRoot,讓我們一起看看為何在第一個地方需要 forRoot

當你導入一個模塊時,通常會使用該模塊的引用:

@NgModule({ providers: [AService] })
export class A {}

@NgModule({ imports: [A] })
export class B {}

這種情況下,在 A 模塊中定義的所有 providers 都會被合并到主注入器,并在整個程序上下文中可用,我想你應該已經知道原因-上文中已經解釋了所有模塊 providers 都會被合并,用來創建注入器。

Angular 也支持另一種方式來導入帶有 providers 的模塊,它不是通過使用模塊的引用來導入,而是傳一個實現了 ModuleWithProviders 接口的對象:

interface ModuleWithProviders { 
   ngModule: Type
   providers?: Provider[] 
}

上文中我們可以這么改寫:

@NgModule({})
class A {}

const moduleWithProviders = {
    ngModule: A,
    providers: [AService]
};

@NgModule({
    imports: [moduleWithProviders]
})
export class B {}

最好能在模塊對象內使用一個靜態方法來返回 ModuleWithProviders,而不是直接使用 ModuleWithProviders 類型的對象,使用 forRoot 方法來重構代碼:

@NgModule({})
class A {
  static forRoot(): ModuleWithProviders {
    return {ngModule: A, providers: [AService]};
  }
}

@NgModule({
  imports: [A.forRoot()]
})
export class B {}

當然對于文中這個簡單示例沒必要定義 forRoot 方法返回 ModuleWithProviders 類型對象,因為可以在兩個模塊內直接定義 providers 或如上文使用一個 moduleWithProviders 對象,這里僅僅也是為了演示效果。然而如果我們想要分割 providers,并在被導入模塊中分別定義這些 providers,那上文中的做法就很有意義了。

比如,如果我們想要為非懶加載模塊定義一個全局的 A 服務,為懶加載模塊定義一個 B 服務,就需要使用上文的方法。我們使用 forRoot 方法為非懶加載模塊返回 providers,使用 forChild 方法為懶加載模塊返回 providers

@NgModule({})
class A {
  static forRoot() {
    return {ngModule: A, providers: [AService]};
  }
  static forChild() {
    return {ngModule: A, providers: [BService]};
  }
}

@NgModule({
  imports: [A.forRoot()]
})
export class NonLazyLoadedModule {}

@NgModule({
  imports: [A.forChild()]
})
export class LazyLoadedModule {}

因為非懶加載模塊會被合并,所以 forRoot 中定義的 providers 全局可用(注:包括非懶加載模塊和懶加載模塊),但是由于懶加載模塊有它自己的注入器,你在 forChild 中定義的 providers 只在當前懶加載模塊內可用(注:不翻譯)。

Please note that the names of methods that you use to return?ModuleWithProviders?structure can be completely arbitrary. The names?forChild?and?forRoot?I used in the examples above are just conventional names recommended by Angular team and used in the?RouterModuleimplementation.(注:即 forRoot 和 forChild 方法名稱可以隨便修改。)

好吧,回到最開始要看的代碼:

@NgModule({
  imports: [
    SomeLibCarouselModule.forRoot(),
    SomeLibCheckboxModule.forRoot(),
    ...

根據上文的理解,就發現沒有必要在每一個模塊里定義 forRoot 方法,因為在多個模塊中定義的 providers 需要全局可用,也沒有為懶加載模塊多帶帶準備 providers(注:即本就沒有切割 providers 的需求,但你使用 forRoot 強制來切割)。甚至,如果一個被導入模塊沒有定義任何 providers,那代碼寫的就更讓人迷惑。

Use forRoot/forChild convention only for shared modules with providers that are going to be imported into both eager and lazy module?modules

還有一個需要注意的是 forRootforChild 僅僅是方法而已,所以可以傳參。比如,@angular/router 包中的 RouterModule,就定義了 forRoot 方法并傳入了額外的參數:

export class RouterModule {
  static forRoot(routes: Routes, config?: ExtraOptions)

傳入的 routes 參數是用來注冊 ROUTES 標識(token)的:

static forRoot(routes: Routes, config?: ExtraOptions) {
  return {
    ngModule: RouterModule,
    providers: [
      {provide: ROUTES, multi: true, useValue: routes}

傳入的第二個可選參數 config 是用來作為配置選項的(注:如配置預加載策略):

static forRoot(routes: Routes, config?: ExtraOptions) {
  return {
    ngModule: RouterModule,
    providers: [
      {
        provide: PreloadingStrategy,
        useExisting: config.preloadingStrategy ?
          config.preloadingStrategy :
          NoPreloading
      }

正如你所看到的,RouterModule 使用了 forRootforChild 方法來分割 providers,并傳入參數來配置相應的 providers

模塊緩存

Stackoverflow 上有段時間有位開發者提了個問題,擔心如果在非懶加載模塊和懶加載模塊導入相同的模塊,在運行時會導致該模塊代碼有重復。這個擔心可以理解,不過不必擔心,因為所有模塊加載器會緩存所有加載的模塊對象。

當 SystemJS 加載一個模塊后會緩存該模塊,下次當懶加載模塊又再次導入該模塊時,SystemJS 模塊加載器會從緩存里取出該模塊,而不是執行網絡請求,這個過程對所有模塊適用(注:Angular 內置了 SystemJsNgModuleLoader 模塊加載器)。比如,當你在寫 Angular 組件時,從 @angular/core 包中導入 Component 裝飾器:

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

你在程序里多處引用了這個包,但是 SystemJS 并不會每次加載這個包,它只會加載一次并緩存起來。

如果你使用 angular-cli 或者自己配置 Webpack,也同樣道理,它只會加載一次并緩存起來,并給它分配一個 ID,其他模塊會使用該 ID 來找到該模塊,從而可以拿到該模塊提供的多種多樣的服務。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/95465.html

相關文章

  • [] 再對 Angular 表單的 ControlValueAccessor 感到迷惑

    摘要:在里我們簡單保存了對回調函數的引用,回調函數是由指令傳入的譯者注參考,只要每次組件值發生改變,就會觸發這個回調函數。 原文鏈接:Never again be confused when implementing ControlValueAccessor in Angular?forms showImg(https://segmentfault.com/img/bV7rR7?w=400...

    blastz 評論0 收藏0
  • @angular/forms 源碼解析之雙向綁定

    摘要:由于的屬性提供了令牌,并且該令牌指向的對象就是,所以構造函數中注入的令牌包含的對象數組只有一個。這樣的構造函數里就會包含一個對象,然后把這個傳給對象,最后注冊回調,這樣以后值更新時就會運行。整個包的設計也是按照這種數據流形式,并不復雜。 我們知道,Angular 的 @angular/forms 包提供了 NgModel 指令,來實現雙向綁定,即把一個 JS 變量(假設為 name)與...

    yangrd 評論0 收藏0
  • 2017-08-23 前端日報

    摘要:前端日報精選免費的計算機編程類中文書籍英文技術文檔看不懂看印記中文就夠了的內部工作原理美團點評點餐前后端分離實踐讓你的動畫坐上時光機中文譯有多棒簡書譯別再使用圖片輪播了掘金譯如何在中使用掘金個讓增長成億美元公司的獨特方法眾成翻 2017-08-23 前端日報 精選 FPB 2.0:免費的計算機編程類中文書籍 2.0英文技術文檔看不懂?看印記中文就夠了!Virtual DOM 的內部工作...

    lordharrd 評論0 收藏0
  • 別再被各種單位迷惑:px/em/rem

    摘要:引自手冊是相對長度單位。所有未經調整的瀏覽器都符合。特點是新增的一個相對單位,根,這個單位引起了廣泛關注。目前,除了及更早版本外,所有瀏覽器均已支持。對于不支持它的瀏覽器,應對方法也很簡單,就是多寫一個絕對單位的聲明。 在他處看到一篇好文章,想記錄在自己的學習筆記中,原文作者看到我轉載若是介意,聯系我立馬就刪除,附上原文鏈接:http://www.huolg.net/html5/htm...

    teren 評論0 收藏0
  • [] 關于 Angular 動態組件你需要知道的

    摘要:第一種方式是使用模塊加載器,如果你使用加載器的話,路由在加載子路由模塊時也是用的作為模塊加載器。還需注意的是,想要使用還需像這樣去注冊它你當然可以在里使用任何標識,不過路由模塊使用標識,所以最好也使用相同。 原文鏈接:Here is what you need to know about dynamic components in?Angular showImg(https://se...

    lcodecorex 評論0 收藏0

發表評論

0條評論

LMou

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<