Angular 文档说
属于 NgModule 的组件共享编译上下文。
你有没有听过类似的错误
警告:模板解析错误:“A”不是已知元素:
如果“b-comp”是一个 Angular 组件,则验证它是否是该模块的一部分。
如果“b-comp”是 Web 组件,则将“CUSTOM_ELEMENTS_SCHEMA”添加到该组件的“@NgModule.schemas”以禁止显示此消息。
或
无法绑定到“ngModel”,因为它不是“输入”的已知属性
编译上下文
您发现,链接中的解释正确地描述了编译上下文的概念。
这是一组将被编译的东西(文件、组件)。这意味着上下文包含编译器需要编译而没有任何错误的所有内容。
假设您编译 typescript 并使用 tsconfig.json 文件控制上下文,其中定义了 files、include 或 exclude 选项。这样,打字稿编译器将仅使用您提供的文件来查找 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 {}
这个组件是在一些 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 用于 typescript 编译器。
同样,在 NgModule 中声明的组件和从导出它们的其他模块导入的组件共享相同的编译上下文(更多内容请参见 Angular 2 Use component from another module)