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

Luk*_* Xu 7 typescript angular

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

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

资源

这里只找到一个解释.但我并不完全理解它或它的重要性.有人可以详细说明"编译上下文"的含义以及模块共享相同上下文的重要性吗?

yur*_*zui 11

Angular文档说明了这一点

属于NgModule 的组件共享编译上下文.

你有没有听过像这样的错误

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

  1. 如果'b-comp'是Angular组件,则验证它是否是此模块的一部分.

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

要么

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


编译上下文

您发现,链接中的解释正确地描述了编译上下文的概念.

它是一组将被编译的东西(文件,组件).它意味着上下文包含编译器需要编译而没有任何错误的所有内容.

想象一下,你编译打字稿,您可以使用控制背景tsconfig.json文件,其中规定files,includeexclude选项.这样,typescript编译器将仅使用您提供的文件来查找ts代码之间的关系.

角度编译器

现在让我们回到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 {}
Run Code Online (Sandbox Code Playgroud)

这个组件在一些Angular模块中定义,如:

@NgModule({
  declarations: [
    ComponentA
  ]
})
export class AModule {}
Run Code Online (Sandbox Code Playgroud)

为了编译ComponentA角度,需要经过以下几个阶段:

1)找到它所属的NgModule.

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

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

Angular正在搜索此NgModule的所有传递模块.(Angular 2使用其他模块的组件)

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

compileComponent(outputCtx, compMeta, ngModule, ngModule.transitiveModule.directives 
                                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Run Code Online (Sandbox Code Playgroud)

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

<div [scroll]="options">
  <b-comp></b-comp>
</div>
Run Code Online (Sandbox Code Playgroud)

因为Angular编译器将使用scroll@Input 查找指令,b-comp但是我们的范围AModule不包含这样的指令.

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

同样,在NgModule和组件中声明的组件,从导出它们的其他模块导入,共享相同的编译上下文(更多关于此处Angular 2使用来自另一个模块的组件)