当我们使用某个总结的知识点解决了某个问题的时候,我们称其为**证真**,即使用现实的问题来验证了自己理论的正确性,在**证真**的过程中我们学习到了新的知识;当我们用历史总结的某个知识点来再次尝试解决类似问题的时候发生了预期外的错误,我们称其为**证伪**,即我们使用现实的问题证明某个已形成的理论是错误的,此时则是我们知识的提升。所以**证伪比证真更重要**。 在3.3.6小节中我们初次接触了`exports`关键字,并有如下说明: ` ② 导出配置过的RouterModule,其它模块若引用该模块(AppRoutingModule),则将自动引用RouterModule。` ![](https://img.kancloud.cn/f8/d2/f8d2735ad3016998f9b97644ef5a3dc7_935x408.png) 但通过对上个小节的学习我们发现以上说法是错误的。因为其它模块自动导入RouterModule的原因是由于其声明在了`imports`,而非`exports`中。也就是说:即使我们不在app-routing.module.ts中进行`exports`声明,app模块仍然是相当于import了RouterModule的。按这个理论,我们尝试删除app-routing.module.ts中`exports`声明的RouterModule。 app-routing.module.ts ``` @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [] }) export class AppRoutingModule { } ``` #### 测试 ![](https://img.kancloud.cn/06/d2/06d2009acdf1ecc64849c432fcb4cdf6_1276x113.png) 测试得到如上错误说不认识`router-outlet`这个组件。由于刚刚删除了`exports`中的RouterModule,所以我们能够马上就定位到是由于该操作造成的。当然也可以推测出`router-outlet`这个组件是属于`RouterModule`的。那么按照前面**找谁帮忙前需要引入该服务所在的模块**的理论,我们尝试直接在App模块中引入`RouterModule`试试看。 app.module.ts ``` imports: [ BrowserModule, AppRoutingModule, HttpClientModule, FormsModule, RouterModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { } ``` 最终的确不报错了。我们认为当前现象最少说明了以下以点: * [ ] **找谁帮忙前需要引入该服务所在的模块**的理论是正确的。 * [ ] imports进行层级依赖的理论是不完全正确的。 * [ ] exports在层级依赖中起着一定的作用。 ## 官方文档 到了这种时候,我们就可以开始尝试使用终极的解决办法**查阅官方文档**了,每当这时候,我们就开始恨自己为什么当初不好好的学习英文的阅读理解部分了。 官方文档对exports这部分进行如下解释: ``` 此 NgModule 中声明的一组组件、指令和管道可以在导入了本模块的模块下任何组件的模板中使用。 导出的这些可声明对象就是该模块的公共 API。 The set of components, directives, and pipes declared in this NgModule that can be used in the template of any component that is part of an NgModule that imports this NgModule. Exported declarations are the module's public API. ``` 虽然angular有相当优秀的官方文档,但有时候看英文的原文会更有韵味,更能让我们理解其中的含意。 我们好像懂了: * [ ] 在exports中声明组件A后,表示其它模块在imports本模块后,可以在自己的模块中使用该组件A。 * [ ] 在exports中声明模块A后,表示其它模块在imports本模块后,可以在自己的模块中使用该模块A中所exports的组件。 * [ ] 在imports中声明模块A后,表示该模块可以使用模块A中所exports的内容(可能是本模块组件、也可能是声明的其它模块中的所有exports内容)。 按上述理论重新绘制系统逻辑图如下: ![](https://img.kancloud.cn/62/01/6201ff3d64131205b81ad410c5a2b839_736x429.png) > 上述的理论也不见得就一定是正确的。但没有任何关系,因为我们的当前理论已经可以证真当前遇到的所有问题了,而这在学习的过程中就足够了。 最后,按上述的理论我们删除掉klass/klass.module.ts中的exports部分。原因是Klass模块未被任何模块imports,当然也就不需要任何的exports了。 klass/klass.module.ts ``` /** * 班级模块 */ @NgModule({ declarations: [IndexComponent, AddComponent, EditComponent], imports: [ CommonModule, FormsModule, ReactiveFormsModule, RouterModule.forChild(routes) ] }) export class KlassModule { } ``` 最后我们进行系统的测试,以保证当前的变更不对历史的功能造成任何影响 。 # 参考文档 | 名称 | 链接 | 预计学习时长(分) | | --- | --- | --- | | 源码地址 | [https://github.com/mengyunzhi/spring-boot-and-angular-guild/releases/tag/step3.4.8](https://github.com/mengyunzhi/spring-boot-and-angular-guild/releases/tag/step3.4.8) | - | | exports | [https://www.angular.cn/api/core/NgModule#exports](https://www.angular.cn/api/core/NgModule#exports) | 5 |