Angular中的编译上下文是什么?

时间:2018-06-20 04:04:17

标签: angular typescript

在Angular文档中,它说模块共享一个编译上下文。

  

NgModules为其组件提供编译上下文。根NgModule始终具有在引导过程中创建的根组件,但是任何NgModule都可以包括任意数量的其他组件,这些组件可以通过路由器加载或通过模板创建。属于NgModule的组件共享一个编译上下文。

source

我只找到一种解释here。但是我不太了解它的重要性。有人可以详细说明“编译上下文”的含义以及模块共享相同上下文的重要性吗?

1 个答案:

答案 0 :(得分:10)

Angular文档说

  

属于NgModule的组件 共享一个编译上下文。

您是否曾经听到过类似的错误

  

警告:模板解析错误:“ A”不是已知元素:

     
      
  1. 如果'b-comp'是Angular组件,则请验证它是否属于此模块。

  2.   
  3. 如果“ b-comp”是Web组件,则将“ CUSTOM_ELEMENTS_SCHEMA”添加到该组件的“ @ NgModule.schemas”以禁止显示此消息。

  4.   

  

由于它不是'input'的已知属性,因此无法绑定到'ngModel'


编译上下文

您已经找到了链接中的解释,正确地描述了编译上下文的概念。

这是一组将被编译的东西(文件,组件)。这意味着上下文包含编译器需要编译的所有内容,而不会出现任何错误。

想象一下您编译打字稿并使用tsconfig.json文件控制上下文,其中定义了filesincludeexclude选项。这样,打字稿编译器将仅使用您提供的文件来查找ts代码之间的关系。

Angular编译器

现在让我们回到Angular编译器。

Angular编译器基本上可以编译组件的模板。要编译模板,Angular应该知道此模板中涉及的所有组件/指令。

假设我们具有以下简单的组件:

@Component({
  selector: 'a-comp`,
  template: `
    <h2>Hello, I'm a-comp</h2>
    <div [scroll]="options">
      <b-comp></b-comp>
    </div>
  `
})
export class ComponentA {}

,此组件在某些Angular模块中定义,例如:

@NgModule({
  declarations: [
    ComponentA
  ]
})
export class AModule {}

为了编译ComponentA,angular需要经历以下几个阶段:

1)找到它所属的NgModule。

ComponentA在AModule中声明,因此该模块成为其编译上下文。

2)查找此模块范围内的所有其他指令。

Angular正在搜索此NgModule的所有传递模块。 (Angular 2 Use component from another module

3)通过将所有涉及的指令传递给编译器来运行编译

compileComponent(outputCtx, compMeta, ngModule, ngModule.transitiveModule.directives 
                                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

我们的AModule不导入任何其他模块,也没有定义任何其他指令。这意味着Angular将无法编译ComponentA的模板(如果您当然不使用CUSTOM_ELEMENTS_SCHEMA的话):

<div [scroll]="options">
  <b-comp></b-comp>
</div>

因为Angular编译器将使用scroll @Input和b-comp查找指令,但我们的范围AModule不包含此类指令。

换句话说,NgModule没有提供用于构建组件的正确编译上下文。 NgModule是Angular编译器的一种配置,例如tsconfig.json用于打字稿编译器。

同样,在NgModule中声明的组件和从导出它们的其他模块导入的组件共享相同的编译上下文(有关更多信息,请参见Angular 2 Use component from another module