1. 请阐述 Angular 的工作原理
Angular 的工作流程涉及多个关键环节,从组件交互到浏览器渲染,以下是其核心流程:
组件交互:当用户触发特定事件(如点击按钮)时,组件会响应这些交互,并可能进一步调用服务层的功能。
服务层:服务层通常由可注入类构成,负责处理业务逻辑或与外部系统交互。组件通过调用服务层的方法(如使用 HttpClient 发送 HTTP 请求)来获取数据或执行操作。
请求处理: Angular 采用 RxJS 的 Observables 来处理异步请求,确保数据的实时性和响应性。 HttpClientModule 内部使用 XHR(XMLHttpRequest)或 Fetch API 来发送 HTTP 请求。 Angular 拦截器可以在请求发送前全局修改请求(例如,添加身份验证令牌),增强了请求的灵活性和安全性。
浏览器渲染: Angular 使用 Zone.js 来检测应用程序状态的变化,确保视图与数据保持同步。 当请求得到解析时,ChangeDetectorRef 会检测到数据的变化,并触发视图的更新。 DOM 通过 Angular 的渲染引擎(Ivy)进行更新,提高了渲染效率和性能。 浏览器的渲染树会根据需要重新评估和重新绘制,以反映最新的视图状态。
2. 什么是 package-lock.json?
package-lock.json 是 npm 在安装软件包时自动生成的一个文件,其核心作用是确保跨环境安装的软件包版本完全一致。它锁定了: 每个软件包的确切版本。 依赖树的完整结构。 通过维护这种确定性安装,package-lock.json 有效防止了“它在我的计算机上运行”的问题,确保了开发环境和生产环境的一致性。
3. Angular 中的依赖注入(DI)是什么?
依赖注入(DI)是一种设计模式,在 Angular 中,它允许框架为组件、管道或其他服务提供所需的依赖项(如其他服务)。Angular 的 DI 系统基于注入器树实现:
根注入器:用于创建单例服务,确保服务在整个应用程序中只有一个实例。
组件注入器:用于创建范围服务,服务的作用域仅限于特定的组件或其子组件。
依赖注入通过 @Injectable() 装饰器和构造函数注入来实现,提高了代码的可测试性和可维护性。
4. 组件之间如何传递数据?
在 Angular 中,组件之间可以通过多种方式传递数据:
父级到子级:使用 @Input() 绑定,允许父组件将数据传递给子组件。
子级到父级:将 @Output() 与 EventEmitter 结合使用,允许子组件向父组件发送事件和数据。
不相关的组件之间:使用 RxJS 的 Subject 或 BehaviorSubject 的共享服务,实现跨组件的数据共享。
路由参数或查询参数:通过路由传递数据,适用于需要跨页面共享的数据。
NgRx Store:用于状态驱动的通信,适合复杂的应用程序状态管理。
5. 不同类型的 RxJS
Subject RxJS 提供了多种类型的 Subject,以满足不同的需求:
Subject:多播 Observable,不保存当前值,新订阅者不会收到之前发送的值。 BehaviorSubject:需要初始值,并向新订阅者发送最新值,确保新订阅者能够获取到最新的数据状态。
ReplaySubject:向新订阅者重播指定数量的已发送值,适用于需要回顾历史数据的场景。 AsyncSubject:仅发送最后一个值,并在完成后结束,适用于只需要最终结果的场景。
6. NgRx 的构建模块是什么?
NgRx 是一个用于管理 Angular 应用程序状态的库,其核心构建模块包括:
存储(Store):集中状态容器,用于存储应用程序的所有状态。
动作(Actions):描述状态变化的事件,通常由用户交互或系统事件触发。
Reducers:纯函数,用于根据动作处理状态变化,返回新的状态。
选择器(Selectors):检索状态片段,提供对状态的只读访问。
效果(Effects):使用 RxJS 处理副作用(如 API 调用),将副作用与状态更新分离。
实体(Entities):简化集合上的 CRUD 操作,提供了一种结构化的方式来管理应用程序中的实体数据。