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

資訊專欄INFORMATION COLUMN

[譯] 關(guān)于 Angular 依賴注入你需要知道的

Edison / 3169人閱讀

摘要:注入器樹(shù)大多數(shù)開(kāi)發(fā)者知道,會(huì)創(chuàng)建根注入器,根注入器內(nèi)的服務(wù)都是單例的。也會(huì)被添加到這個(gè)根注入器對(duì)象內(nèi),它主要用來(lái)創(chuàng)建動(dòng)態(tài)組件,因?yàn)樗鎯?chǔ)了屬性指向的組件數(shù)組。為了理解依賴解析算法,我們首先需要知道視圖和父視圖元素概念。

What you always wanted to know about Angular Dependency Injection tree

如果你之前沒(méi)有深入了解 Angular 依賴注入系統(tǒng),那你現(xiàn)在可能認(rèn)為 Angular 程序內(nèi)的根注入器包含所有合并的服務(wù)提供商,每一個(gè)組件都有它自己的注入器,延遲加載模塊有它自己的注入器。

但是,僅僅知道這些可能還不夠呢?

不久前有個(gè)叫 Tree-Shakeable Tokens feature 被合并到 master 分支,如果你和我一樣充滿好奇心,可能也想知道這個(gè) feature 改變了哪些東西。

所以現(xiàn)在去看看,可能有意外收獲嗷。

注入器樹(shù)(Injector Tree)

大多數(shù)開(kāi)發(fā)者知道,Angular 會(huì)創(chuàng)建根注入器,根注入器內(nèi)的服務(wù)都是單例的。但是,貌似還有其他注入器是它的父級(jí)。

作為一名開(kāi)發(fā)者,我想知道 Angular 是怎么構(gòu)建注入器樹(shù)的,下圖是注入器樹(shù)的頂層部分:

這不是整棵樹(shù),目前還沒(méi)有任何組件呢,后面會(huì)繼續(xù)畫(huà)樹(shù)的剩余部分。但是現(xiàn)在先看下根注入器 AppModule Injector,因?yàn)樗亲畛J褂玫摹?/p> 根注入器(Root AppModule Injector)

我們知道 Angular 程序根注入器 就是上圖的 AppModule Injector,上文說(shuō)了,這個(gè)根注入器包含所有中間模塊的服務(wù)提供商,也就是說(shuō)(注:不翻譯):

If we have a module with some providers and import this module directly in AppModule or in any other module, which has already been imported in AppModule, then those providers become application-wide providers.

根據(jù)這個(gè)規(guī)則,上圖中 EagerModule2MyService2 也會(huì)被包含在根注入器 AppModule Injector 中。

ComponentFactoryResolver 也會(huì)被 Angular 添加 到這個(gè)根注入器對(duì)象內(nèi),它主要用來(lái)創(chuàng)建動(dòng)態(tài)組件,因?yàn)樗鎯?chǔ)了 entryComponents 屬性指向的組件數(shù)組。

值得注意的是,所有服務(wù)提供商中有 Module Tokens,它們都是被導(dǎo)入模塊的類名。后面探索到 tree-shakeable tokens 時(shí)候,還會(huì)回到這個(gè) Module Tokens 話題。

Angular 使用 AppModule 工廠函數(shù)來(lái)實(shí)例化根注入器 AppModule Injector,這個(gè) AppModule 工廠函數(shù)就在所謂的 module.ngfactory.js 文件內(nèi):

我們可以看到這個(gè)工廠函數(shù)返回一個(gè)包含所有被合并服務(wù)提供商的模塊對(duì)象,所有開(kāi)發(fā)者都應(yīng)當(dāng)熟悉這個(gè)(注:可以查看 譯 Angular 的 @Host 裝飾器和元素注入器)。

Tip: If you have angular application in dev mode and want to see all providers from root AppModule injector then just open devtools console and write:
ng.probe(getAllAngularRootElements()[0]).injector.view.root.ngModule._providers

還有很多其他知識(shí)點(diǎn),我在這里沒(méi)有描述,因?yàn)楣倬W(wǎng)上已經(jīng)談到了:

https://angular.io/guide/ngmodule-faq

https://angular.io/guide/hierarchical-dependency-injection

Platform Injector

實(shí)際上,根注入器 AppModule Injector 有個(gè)父注入器 NgZoneInjector,而它又是 PlatformInjector 的子注入器。

PlatformInjector 會(huì)在 PlatformRef 對(duì)象初始化的時(shí)候,包含內(nèi)置的服務(wù)提供商,但也可以額外包含服務(wù)提供商:

const platform = platformBrowserDynamic([ { 
  provide: SharedService, 
  deps:[] 
}]);
platform.bootstrapModule(AppModule);
platform.bootstrapModule(AppModule2);

這些額外的服務(wù)提供商是由我們開(kāi)發(fā)者傳入的,且必須是 StaticProviders。如果你不熟悉 StaticProvidersProvider 兩者間的區(qū)別,可以查看這個(gè) StackOverflow 的答案

Tip: If you have angular application in dev mode and want to see all providers from Platform injector then just open devtools console and write:
ng.probe(getAllAngularRootElements()[0]).injector.view.root.ngModule._parent.parent._records;

// to see stringified value use
ng.probe(getAllAngularRootElements()[0]).injector.view.root.ngModule._parent.parent.toString();

盡管根注入器以及其父注入器解析依賴的過(guò)程清晰明了,但是組件級(jí)別的注入器如何解析依賴卻讓我很困惑,所以,我接著去深入了解。

EntryComponent and RootData

我在上文聊到 ComponentFactoryResolver 時(shí),就涉及到 entryComponents 入口組件。這些入口組件會(huì)在 NgModule 的 bootstrapentryComponents 屬性中聲明,@angular/router 也會(huì)用它們動(dòng)態(tài)創(chuàng)建組件。

Angular 會(huì)為所有入口組件創(chuàng)建宿主工廠函數(shù),這些宿主工廠函數(shù)就是其他視圖的根視圖,也就是說(shuō)(注:不翻譯):

Every time we create dynamic component angular creates root view with root data, that contains references to elInjector and ngModule injector.
function createRootData(
    elInjector: Injector, ngModule: NgModuleRef, rendererFactory: RendererFactory2,
    projectableNodes: any[][], rootSelectorOrNode: any): RootData {
  const sanitizer = ngModule.injector.get(Sanitizer);
  const errorHandler = ngModule.injector.get(ErrorHandler);
  const renderer = rendererFactory.createRenderer(null, null);
  return {
    ngModule,
    injector: elInjector, projectableNodes,
    selectorOrNode: rootSelectorOrNode, sanitizer, rendererFactory, renderer, errorHandler
  };
}

假設(shè)現(xiàn)在正在運(yùn)行一個(gè) Angular 程序。

下面代碼執(zhí)行時(shí),其內(nèi)部發(fā)生了什么:

platformBrowserDynamic().bootstrapModule(AppModule);

事實(shí)上,其內(nèi)部發(fā)生了很多事情,但是我們僅僅對(duì) Angular 是 如何創(chuàng)建入口組件 這塊感興趣:

const compRef = componentFactory.create(Injector.NULL, [], selectorOrNode, ngModule);

Angular 注入樹(shù)就是從這里開(kāi)始,分叉為兩顆并行樹(shù)。

Element Injector vs Module Injector

不久前,當(dāng)延遲加載模塊被廣泛使用時(shí),在 github 上 有人報(bào)告了一個(gè)奇怪的案例:依賴注入系統(tǒng)會(huì)兩次實(shí)例化延遲加載模塊。結(jié)果,一個(gè)新的設(shè)計(jì)被引入。所以,從那開(kāi)始,Angular 有兩個(gè)并行注入樹(shù):元素注入樹(shù)和模塊注入樹(shù)。

主要規(guī)則是:當(dāng)組件或指令需要解析依賴時(shí),Angular 使用 Merge Injector 來(lái)遍歷 element injector tree,如果沒(méi)找到該依賴,則遍歷 module injector tree 去查找依賴。

Please note I don"t use phrase "component injector" but rather "element injector".

什么是 Merge Injector?

你以前可能寫(xiě)過(guò)如下類似代碼:

@Directive({
  selector: "[someDir]"
}
export class SomeDirective {
 constructor(private injector: Injector) {}
}

這里的 injector 就是 Merge Injector,當(dāng)然你也可以在組件中注入這個(gè) Merge Injector

Merge Injector 對(duì)象的定義如下:

class Injector_ implements Injector {
  constructor(private view: ViewData, private elDef: NodeDef|null) {}
  get(token: any, notFoundValue: any = Injector.THROW_IF_NOT_FOUND): any {
    const allowPrivateServices =
        this.elDef ? (this.elDef.flags & NodeFlags.ComponentView) !== 0 : false;
    return Services.resolveDep(
        this.view, this.elDef, allowPrivateServices,
        {flags: DepFlags.None, token, tokenKey: tokenKey(token)}, notFoundValue);
  }
}

如上代碼顯示了 Merge Injector 僅僅是視圖和元素的組合,這個(gè)注入器充當(dāng)依賴解析時(shí) element injector treemodule injector tree 之間的橋梁。

Merge Injector 也可以解析內(nèi)置的對(duì)象,如 ElementRefViewContainerRefTemplateRefChangeDetectorRef 等等,更有趣的是,它還可以返回 Merge Injector

基本上每一個(gè) DOM 元素都有一個(gè) merge injector,即使沒(méi)有提供任何令牌。

Tip: to get merge injector just open console and write:
ng.probe($0).injector

但是你可能會(huì)問(wèn) element injector 是什么?

我們知道 @angular/compiler 會(huì)編譯組件模板生成工廠函數(shù),該函數(shù)實(shí)際上只是調(diào)用 viewDef() 函數(shù)返回 ViewDefinition 類型對(duì)象,視圖僅僅是模板的一種表現(xiàn)形式,里面包含各種類型節(jié)點(diǎn),如 directivetextproviderquery 等等。其中有元素節(jié)點(diǎn) element node 用來(lái)表示 DOM 元素的。實(shí)際上,元素注入器 element injector 就在這個(gè)節(jié)點(diǎn)內(nèi)。Angular 會(huì)把該元素節(jié)點(diǎn)上所有的服務(wù)提供商都存儲(chǔ)在該節(jié)點(diǎn)的兩個(gè)屬性里:

export interface ElementDef {
  ...
  /**
   * visible public providers for DI in the view,
   * as see from this element. This does not include private providers.
   */
  publicProviders: {[tokenKey: string]: NodeDef}|null;
  /**
   * same as visiblePublicProviders, but also includes private providers
   * that are located on this element.
   */
  allProviders: {[tokenKey: string]: NodeDef}|null;
}

讓我們看看 元素注入器是如何解析依賴的

const providerDef =
  (allowPrivateServices ? elDef.element!.allProviders :
    elDef.element!.publicProviders)![tokenKey];
if (providerDef) {
  let providerData = asProviderData(searchView, providerDef.nodeIndex);
  if (!providerData) {
    providerData = { instance: _createProviderInstance(searchView, providerDef) };
    searchView.nodes[providerDef.nodeIndex] = providerData as any;
  }
  return providerData.instance;
}

這里僅僅檢查 allProviders 屬性,或依據(jù)私有性檢查 publicProviders

這個(gè)注入器包含組件/指令對(duì)象,和其中的所有服務(wù)提供商。

視圖實(shí)例化階段 時(shí)主要由 ProviderElementContext 對(duì)象提供這些服務(wù)提供商,該對(duì)象也是 @angular/compiler Angular 編譯器的一部分。如果我們深入挖掘這個(gè)對(duì)象,會(huì)發(fā)現(xiàn)一些有趣的事情。

比如說(shuō),當(dāng)使用 @Host 裝飾器時(shí)會(huì)有一些 限制,可以使用宿主元素的 viewProviders 屬性來(lái)解決這些限制,可以查看 https://medium.com/@a.yurich.... 。

另一個(gè)有趣的事情是,如果組件宿主元素上掛載指令,但組件和指令提供相同的令牌,則指令的服務(wù)提供商會(huì) 勝出

Tip: to get element injector just open console and write:
ng.probe($0).injector.elDef.element

依賴解析算法

視圖內(nèi)依賴解析算法代碼是 resolveDep() 函數(shù)merge injectorget() 方法中也是使用這個(gè)函數(shù)來(lái)解析依賴(Services.resolveDep)。為了理解依賴解析算法,我們首先需要知道視圖和父視圖元素概念。

如果根組件有模板 ,我們就會(huì)有三個(gè)視圖:

HostView_AppComponent
    
View_AppComponent
    
View_ChildComponent
    some content

依賴解析算法會(huì)根據(jù)多級(jí)視圖來(lái)解析:

如果子組件需要解析依賴,那 Angular 會(huì)首先查找該組件的元素注入器,也就是檢查 elRef.element.allProviders|publicProviders,然后 向上遍歷父視圖元素 檢查元素注入器的服務(wù)提供商(1),直到父視圖元素等于 null(2), 則返回 startView(3),然后檢查 startView.rootData.elnjector(4),最后,只有當(dāng)令牌沒(méi)找到,再去檢查 startView.rootData module.injector(5)。(注:元素注入器 -> 組件注入器 -> 模塊注入器)

當(dāng)向上遍歷組件視圖來(lái)解析依賴時(shí),會(huì)搜索 視圖的父元素而不是元素的父元素。Angular 使用 viewParentEl() 函數(shù)獲取視圖父元素:

/**
 * for component views, this is the host element.
 * for embedded views, this is the index of the parent node
 * that contains the view container.
 */
export function viewParentEl(view: ViewData): NodeDef|null {
  const parentView = view.parent;
  if (parentView) {
    return view.parentNodeDef !.parent;
  } else {
    return null;
  }
}

比如說(shuō),假設(shè)有如下的一段小程序:

@Component({
  selector: "my-app",
  template: ``
})
export class AppComponent {}

@Component({
  selector: "my-list",
  template: `
    
1 2 3
` }) export class MyListComponent {} @Component({ selector: "grid-list", template: `` }) export class GridListComponent {} @Component({ selector: "grid-tile", template: `...` }) export class GridTileComponent { constructor(private gridList: GridListComponent) {} }

假設(shè) grid-tile 組件依賴 GridListComponent,我們可以成功拿到該組件對(duì)象。但是這是怎么做到的?

這里父視圖元素究竟是什么?

下面的步驟回答了這個(gè)問(wèn)題:

查找 起始元素GridListComponent 組件模板里包含 grid-tile 元素選擇器,因此需要找到匹配 grid-tile 選擇器的元素。所以起始元素就是 grid-tile 元素。

查找擁有 grid-tile 元素的 模板,也就是 MyListComponent 組件模板。

決定該元素的視圖。如果沒(méi)有父嵌入視圖,則為組件視圖,否則為嵌入視圖。grid-tile 元素之上沒(méi)有任何 ng-template*structuralDirective,所以這里是組件視圖 View_MyListComponent

查找視圖的父元素。這里是視圖的父元素,而不是元素的父元素。

這里有兩種情況:

對(duì)于嵌入視圖,父元素則為包含該嵌入視圖的視圖容器。

比如,假設(shè) grid-list 上掛載有結(jié)構(gòu)指令:

@Component({
  selector: "my-list",
  template: `
    
1 2 3
` }) export class MyListComponent {}

grid-tile 視圖的父元素則是 div.container

對(duì)于組件視圖,父元素則為宿主元素。

我們上面的小程序也就是組件視圖,所以父視圖元素是 my-list 元素,而不是 grid-list

現(xiàn)在,你可能想知道如果 Angular 跳過(guò) grid-list,則它是怎么解析 GridListComponent 依賴的?

關(guān)鍵是 Angular 使用 原型鏈繼承 來(lái)搜集服務(wù)提供商:

每次我們?yōu)橐粋€(gè)元素提供服務(wù)提供商時(shí),Angular 會(huì)新創(chuàng)建繼承于父節(jié)點(diǎn)的 allProviderspublicProviders 數(shù)組,否則不會(huì)新創(chuàng)建,僅僅會(huì)共享父節(jié)點(diǎn)的這兩個(gè)數(shù)組。

這就表示了 grid-tile 包含當(dāng)前視圖內(nèi)所有父元素的所有服務(wù)提供商。

下圖基本說(shuō)明了 Angular 是如何為模板內(nèi)元素收集服務(wù)提供商:

正如上圖顯示的,grid-tile 使用元素注入器通過(guò) allProviders 成功拿到 GridListComponent 依賴,因?yàn)?grid-tile 元素注入器包含來(lái)自于父元素的服務(wù)提供商。

想要了解更多,可以查看 StackOverflow answer

元素注入器的服務(wù)提供商使用了原型鏈繼承,導(dǎo)致我們不能使用 multi 選項(xiàng)來(lái)提供同一令牌多個(gè)服務(wù)。但是由于依賴注入系統(tǒng)很靈活,也有辦法去解決這個(gè)問(wèn)題,可以查看 https://stackoverflow.com/que...。

可以把上文的解釋裝入腦中,現(xiàn)在繼續(xù)畫(huà)注入樹(shù)。

Simple my-app->child->grand-child application

假設(shè)有如下簡(jiǎn)單程序:

@Component({
  selector: "my-app",
  template: ``,
})
export class AppComponent {}

@Component({
  selector: "child",
  template: ``
})
export class ChildComponent {}

@Component({
  selector: "grand-child",
  template: `grand-child`
})
export class GrandChildComponent {
  constructor(private service: Service) {}
}

@NgModule({
  imports: [BrowserModule],
  declarations: [
    AppComponent, 
    ChildComponent, 
    GrandChildComponent
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

我們有三層樹(shù)結(jié)構(gòu),并且 GrandChildComponent 依賴于 Service

my-app
   child
      grand-child(ask for Service dependency)

下圖解釋了 Angular 內(nèi)部是如何解析 Service 依賴的:

上圖從 View_Child (1)的 grand-child 元素開(kāi)始,并向上遍歷查找所有視圖的父元素,當(dāng)視圖沒(méi)有父元素時(shí),本實(shí)例中 may-app 沒(méi)有父元素,則 使用根視圖的注入器查找(2):

startView.root.injector.get(depDef.token, NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR);

本實(shí)例中 startView.root.injector 就是 NullInjector,由于 NullInjector 沒(méi)有任何服務(wù)提供商,則 Angular 就會(huì) 切換到模塊注入器(3):

startView.root.ngModule.injector.get(depDef.token, notFoundValue);

所以 Angular 會(huì)按照以下順序解析依賴:

AppModule Injector 
        ||
        /
    ZoneInjector 
        ||
        /
  Platform Injector 
        ||
        /
    NullInjector 
        ||
        /
       Error
路由程序

讓我們修改程序,添加路由器:

@Component({
  selector: "my-app",
  template: ``,
})
export class AppComponent {}
...
@NgModule({
  imports: [
    BrowserModule,
    RouterModule.forRoot([
      { path: "child", component: ChildComponent },
      { path: "", redirectTo: "/child", pathMatch: "full" }
    ])
  ],
  declarations: [
    AppComponent,
    ChildComponent,
    GrandChildComponent
  ],
  bootstrap: [ AppComponent ]
})
export class AppModule { }

這樣視圖樹(shù)就類似為:

my-app
   router-outlet
   child
      grand-child(dynamic creation)

現(xiàn)在讓我們看看 路由是如何創(chuàng)建動(dòng)態(tài)組件的

const injector = new OutletInjector(activatedRoute, childContexts, this.location.injector);                           
this.activated = this.location.createComponent(factory, this.location.length, injector);

這里 Angular 使用新的 rootData 對(duì)象創(chuàng)建一個(gè)新的根視圖,同時(shí)傳入 OutletInjector 作為根元素注入器 elInjectorOutletInjector 又依賴于父注入器 this.location.injector,該父注入器是 router-outlet 的元素注入器。

OutletInjector 是一種特別的注入器,行為有些像路由組件和父元素 router-outlet 之間的橋梁,該對(duì)象代碼可以看 這里

延遲加載程序

最后,讓我們把 GrandChildComponent 移到延遲加載模塊,為此需要在子組件中添加 router-outlet,并修改路由配置:

@Component({
  selector: "child",
  template: `
    Child
    
  `
})
export class ChildComponent {}
...
@NgModule({
  imports: [
    BrowserModule,
    RouterModule.forRoot([
      {
        path: "child", component: ChildComponent,
        children: [
          { 
             path: "grand-child", 
             loadChildren: "./grand-child/grand-child.module#GrandChildModule"}
        ]
      },
      { path: "", redirectTo: "/child", pathMatch: "full" }
    ])
  ],
  declarations: [
    AppComponent,
    ChildComponent
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}
my-app
   router-outlet
   child (dynamic creation)
       router-outlet
         +grand-child(lazy loading)

讓我們?yōu)檠舆t加載程序畫(huà)兩顆獨(dú)立的樹(shù):

Tree-shakeable tokens are on horizon

Angular 團(tuán)隊(duì)為讓框架變得更小,后續(xù)又做了大量工作,從 version 6 開(kāi)始,提供了另一種注冊(cè)服務(wù)提供商的方式。

Injectable

之前由 Injectable 裝飾的類不能說(shuō)明它是否有依賴,與它如何被使用也無(wú)關(guān)。所以,如果一個(gè)服務(wù)沒(méi)有依賴,那 Injectable 裝飾器是可以被移除的。

隨著 API 變得穩(wěn)定,可以配置 Injectable 裝飾器來(lái)告訴 Angular,該服務(wù)是屬于哪一個(gè)模塊的,以及它是被如何實(shí)例化的:

export interface InjectableDecorator {
  (): any;
  (options?: {providedIn: Type| "root" | null}&InjectableProvider): any;
  new (): Injectable;
  new (options?: {providedIn: Type| "root" | null}&InjectableProvider): Injectable;
}

export type InjectableProvider = ValueSansProvider | ExistingSansProvider |
StaticClassSansProvider | ConstructorSansProvider | FactorySansProvider | ClassSansProvider;

下面是一個(gè)簡(jiǎn)單實(shí)用案例:

@Injectable({
  providedIn: "root"
})
export class SomeService {}

@Injectable({
  providedIn: "root",
  useClass: MyService,
  deps: []
})
export class AnotherService {}

ngModule factory 包含所有服務(wù)提供商不同,這里把有關(guān)服務(wù)提供商的信息存儲(chǔ)在 Injectable 裝飾器內(nèi)。這個(gè)技術(shù)會(huì)讓我們程序代碼變得更小,因?yàn)闆](méi)有被使用的服務(wù)會(huì)被搖樹(shù)優(yōu)化掉。如果我們使用 Injectable 來(lái)注冊(cè)服務(wù)提供商,而使用者又不導(dǎo)入我們的服務(wù)提供商,那最后被打包的代碼不包含這些服務(wù)提供商,所以,

Prefer registering providers in Injectables over NgModule.providers over Component.providers

本文開(kāi)始時(shí)我提到過(guò)根注入器的 Modules Tokens,所以 Angular 能夠區(qū)分哪一個(gè)模塊出現(xiàn)在特定的模塊注入器內(nèi)。

依賴解析器會(huì)使用這個(gè)信息來(lái) 判斷可搖樹(shù)優(yōu)化令牌是否屬于模塊注入器

InjectionToken

可以使用 InjectionToken 對(duì)象來(lái)定義依賴注入系統(tǒng)如何構(gòu)造一個(gè)令牌以及該令牌應(yīng)用于哪一個(gè)注入器:

export class InjectionToken {
  constructor(protected _desc: string, options?: {
    providedIn?: Type| "root" | null,
    factory: () => T
  }) {}
}

所以應(yīng)該這樣使用:

export const apiUrl = new InjectionToken("tree-shakeable apiUrl token", {                                   
  providedIn: "root",                               
  factory: () => "someUrl"
});
結(jié)論

依賴注入是 Angular 框架中的一個(gè)非常復(fù)雜的話題,知道其內(nèi)部工作原理會(huì)讓你對(duì)你做的事情更有信心,所以我強(qiáng)烈建議偶爾去深入研究 Angular 源代碼。

注:這篇文章很有深度,很長(zhǎng)也很難,加油吧!

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/108392.html

相關(guān)文章

  • [] Angular @Host 裝飾器和元素注入

    摘要:裝飾器我們?yōu)樯兑懻撛刈⑷肫鞫皇茄b飾器這是因?yàn)闀?huì)把元素注入器依賴解析過(guò)程限制在當(dāng)前組件視圖內(nèi)。但是一旦使用了裝飾器,整個(gè)依賴解析過(guò)程就會(huì)在第一階段完成后停止解析,也就是說(shuō),元素注入器只在組件視圖內(nèi)解析依賴,然后就停止解析工作。 原文鏈接:A curious case of the @Host decorator and Element Injectors in Angular 我...

    marek 評(píng)論0 收藏0
  • [] 別再對(duì) Angular Modules 感到迷惑

    摘要:大多數(shù)初學(xué)者會(huì)認(rèn)為也有封裝規(guī)則,但實(shí)際上沒(méi)有。第二個(gè)規(guī)則是最后導(dǎo)入模塊的,會(huì)覆蓋前面導(dǎo)入模塊的。 原文鏈接:Avoiding common confusions with modules in Angular showImg(https://segmentfault.com/img/remote/1460000015298243?w=270&h=360); Angular Modul...

    LMou 評(píng)論0 收藏0
  • [] 如何使用 TypeScript 編寫(xiě) AngularJS Controller?

    摘要:在這篇文章里,我將介紹如何使用去編寫(xiě)的。一個(gè)新的子將被創(chuàng)建并作為變量注入到的構(gòu)造函數(shù)當(dāng)中。當(dāng)使用一個(gè)構(gòu)造函數(shù)就可以很好地解決問(wèn)題,因?yàn)楹瘮?shù)提升起到了很重要的作用。自定義接口類型接著就可以在構(gòu)造器使用參數(shù)獲得強(qiáng)類型和智能支持了。 原文鏈接 : How to write AngularJS controller using TypeScript?原文作者 : Siddharth Pande...

    alphahans 評(píng)論0 收藏0
  • [] 關(guān)于 `ExpressionChangedAfterItHasBeenCheckedErro

    摘要:本文將解釋引起這個(gè)錯(cuò)誤的內(nèi)在原因,檢測(cè)機(jī)制的內(nèi)部原理,提供導(dǎo)致這個(gè)錯(cuò)誤的共同行為,并給出修復(fù)這個(gè)錯(cuò)誤的解決方案。這一次過(guò)程稱為。這個(gè)程序設(shè)計(jì)為子組件拋出一個(gè)事件,而父組件監(jiān)聽(tīng)這個(gè)事件,而這個(gè)事件會(huì)引起父組件屬性值發(fā)生改變。 原文鏈接:Everything you need to know about the ExpressionChangedAfterItHasBeenCheckedE...

    andong777 評(píng)論0 收藏0
  • [] 關(guān)于 Angular 動(dòng)態(tài)組件需要知道

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

    lcodecorex 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<