angular / angular/components

bug(multiple): services provided in root are also provided in NgModules

未关闭
#28,443 1 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看
area: many P3
主要语言
TypeScript
星标
25k
派生
6.8k
平均合并
1 天 8 小时
30 天内合并 PR
91

描述

### Is this a regression?

- [ ] Yes, this behavior used to work in the previous version

### The previous version in which this bug was not present was

_No response_

### Description

I am maintaining an Angular library built on top of Angular Material. Among others, this library includes custom components which are to be opened inside a dialog. Here is what the module of such a component looks like:

```typescript
@NgModule({
declarations: [MyComponent],
imports: [MatDialogModule],
export: [MyComponent],
})
export class MyModule {}
```

For applications which use that component in an NgModule, this works fine. However one of the applications is in the progress of migrating to standalone. After making the component standalone and adding `MyModule` to the `imports`, the unit tests involving the `MatDialog` service opening `MyComponent` failed. After investigation, I found out that the instance injected by the component constructor and the instance injected by `TestBed.inject()` are now two separate ones.

I have confirmed with the Angular core team that this is by design, see https://github.com/angular/angular/issues/53929.

The root cause is that `MatDialogModule` has `MatDialog` in its `providers`: https://github.com/angular/components/blob/b8cf1308571b29622422cd56f7f76b7bbc5ba5b1/src/material/dialog/module.ts#L34

IMHO it should be removed from the providers, as the service is `providedIn: 'root'`.

The `MatSnackBar` has the same issue, there might be more affected services in this repo.

### Reproduction

Repo: https://github.com/json-derulo/ng17-dialog-issue
Steps to reproduce:
1. Run `ng test`

### Expected Behavior

There is only one instance of `MatDialog` and the test case in the repro pass

### Actual Behavior

There are multiple instances of `MatDialog` and the test case in the repro fails

### Environment

Angular CLI: 17.0.10
Node: 18.18.2
Package Manager: npm 9.8.1
OS: darwin x64

Angular: 17.0.9
... animations, common, compiler, compiler-cli, core, forms
... platform-browser, platform-browser-dynamic, router

Package Version
---------------------------------------------------------
@angular-devkit/architect 0.1700.10
@angular-devkit/build-angular 17.0.10
@angular-devkit/core 17.0.10
@angular-devkit/schematics 17.0.10
@angular/cdk 17.1.0
@angular/cli 17.0.10
@angular/material 17.1.0
@schematics/angular 17.0.10
rxjs 7.8.1
typescript 5.2.2
zone.js 0.14.3

贡献指南

打开贡献指南

调研方向

从 src/material/dialog/module.ts 中链接的 MatDialogModule 定义开始,并在复现仓库中运行 ng test。检查 MatDialog provider 的声明方式,以及 MatSnackBar 或其他受影响的 service 是否也采用相同模式。当复现代码中只有一个 MatDialog 实例且其测试通过时,即表示完成。

由索引模型根据 Issue 内容生成。

评估

技术栈
angular, typescript
领域
frontend, testing
Issue 类型
缺陷
难度
4/5
预计耗时
3-5 天
活跃度
停滞
描述清晰度
基本清楚
新手友好度
35/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。