Angular 17中Material Dialog数据注入报错问题求助
问题现象
开发编辑用户数据的Angular 17对话框组件时,向对话框注入父组件数据时VSCode抛出两个错误:
No suitable injection token for parameter 'data' of class 'UsersCrudModalComponent'. Consider using the @Inject decorator to specify an injection token.
将@Inject(MAT_DIALOG_DATA)移至构造函数注入项首位时,出现第二个错误:
Unable to resolve signature of parameter decorator when called as an expression. Argument of type '0' is not assignable to parameter of type '3'.
尝试修改tsconfig.json中experimentalDecorators为false后,第一个错误消失,但注入令牌问题仍未解决。
当前代码
父组件代码
editUser(uuid: string) { const user: IUser | undefined = this._users.find((f: IUser) => (f.uuid = uuid)); const dialogRef = this.dialog.open(UsersCrudModalComponent, { data: { user: user } }); }
对话框组件代码
constructor( private readonly _dialogRef: MatDialogRef<LoginModalComponent>, private readonly _usersService: UsersService, private readonly _translate: TranslateService, @Inject(MAT_DIALOG_DATA) public data: { user: IUser }, ) { this.user = this.data.user; }
相关配置文件
tsconfig.json
{ "compileOnSave": false, "compilerOptions": { "baseUrl": "src", "outDir": "./dist/out-tsc", "forceConsistentCasingInFileNames": true, "strict": true, "noImplicitOverride": true, "noPropertyAccessFromIndexSignature": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "esModuleInterop": true, "sourceMap": true, "declaration": false, "experimentalDecorators": true, "moduleResolution": "node", "importHelpers": true, "target": "ES2022", "module": "ES2022", "useDefineForClassFields": false, "lib": ["ES2022", "dom"] }, "angularCompilerOptions": { "enableI18nLegacyMessageIdFormat": false, "strictInjectionParameters": true, "strictInputAccessModifiers": true, "strictTemplates": true } }
angular.json
{ "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "version": 1, "newProjectRoot": "projects", "projects": { "gaia-spa": { "projectType": "application", "schematics": { "@schematics/angular:component": { "style": "scss", "standalone": false }, "@schematics/angular:directive": { "standalone": false }, "@schematics/angular:pipe": { "standalone": false } }, "root": "", "sourceRoot": "src", "prefix": "app", "architect": { "build": { "builder": "@angular-devkit/build-angular:application", "options": { "outputPath": "dist/gaia-spa", "index": "src/index.html", "browser": "src/main.ts", "polyfills": ["zone.js"], "tsConfig": "tsconfig.app.json", "inlineStyleLanguage": "scss", "assets": ["src/favicon.ico", "src/assets"], "styles": [ "@angular/material/prebuilt-themes/pink-bluegrey.css", "src/styles.scss" ], "scripts": ["./node_modules/crypto-js/crypto-js.js"], "server": "src/main.server.ts", "prerender": true, "stylePreprocessorOptions": { "includePaths": ["src/assets"] }, "ssr": { "entry": "server.ts" } }, "configurations": { "production": { "budgets": [ { "type": "initial", "maximumWarning": "500kb", "maximumError": "1mb" }, { "type": "anyComponentStyle", "maximumWarning": "2kb", "maximumError": "4kb" } ], "outputHashing": "all", "fileReplacements": [ { "replace": "src/environments/environment.ts", "with": "src/environments/environment.prod.ts" } ] }, "development": { "optimization": false, "extractLicenses": false, "sourceMap": true, "namedChunks": true, "fileReplacements": [ { "replace": "src/environments/environment.ts", "with": "src/environments/environment.dev.ts" } ] } }, "defaultConfiguration": "production" }, "serve": { "builder": "@angular-devkit/build-angular:dev-server", "configurations": { "production": { "buildTarget": "gaia-spa:build:production" }, "development": { "buildTarget": "gaia-spa:build:development" } }, "defaultConfiguration": "development" }, "extract-i18n": { "builder": "@angular-devkit/build-angular:extract-i18n", "options": { "buildTarget": "gaia-spa:build" } }, "test": { "builder": "@angular-devkit/build-angular:karma", "options": { "polyfills": ["zone.js", "zone.js/testing"], "tsConfig": "tsconfig.spec.json", "inlineStyleLanguage": "scss", "assets": ["src/favicon.ico", "src/assets"], "styles": [ "@angular/material/prebuilt-themes/pink-bluegrey.css", "src/styles.scss" ], "scripts": [] } } } } }, "cli": { "analytics": "(private)" } }
package.json
{ "name": "gaia-spa", "version": "0.0.0", "scripts": { "ng": "ng", "start": "ng serve", "start:dev": "ng serve --configuration development", "build": "ng build", "watch": "ng build --watch --configuration development", "test": "ng test", "serve:ssr:gaia-spa": "node dist/gaia-spa/server/server.mjs" }, "private": true, "dependencies": { "@angular/animations": "^17.0.0", "@angular/cdk": "^17.0.5", "@angular/common": "^17.0.0", "@angular/compiler": "^17.0.0", "@angular/core": "^17.0.0", "@angular/forms": "^17.0.0", "@angular/material": "^17.0.3", "@angular/platform-browser": "^17.0.0", "@angular/platform-browser-dynamic": "^17.0.0", "@angular/platform-server": "^17.0.0", "@angular/router": "^17.0.0", "@angular/ssr": "^17.0.5", "@fortawesome/angular-fontawesome": "^0.14.1", "@fortawesome/fontawesome-svg-core": "^6.5.1", "@fortawesome/free-solid-svg-icons": "^6.5.1", "@ngx-translate/core": "^15.0.0", "@ngx-translate/http-loader": "^8.0.0", "@types/crypto-js": "^4.2.1", "crypto-js": "^4.2.0", "express": "^4.18.2", "intl": "^1.2.5", "ngx-bootstrap": "^6.2.0", "ngx-webstorage": "^13.0.1", "rxjs": "~7.8.0", "tslib": "^2.3.0", "zone.js": "~0.14.2" }, "devDependencies": { "@angular-devkit/build-angular": "^17.0.5", "@angular/cli": "^17.0.5", "@angular/compiler-cli": "^17.0.0", "@angular/localize": "^17.0.5", "@types/core-js": "^2.5.8", "@types/express": "^4.17.17", "@types/jasmine": "~5.1.0", "@types/node": "^18.18.0", "jasmine-core": "~5.1.0", "karma": "~6.4.0", "karma-chrome-launcher": "~3.2.0", "karma-coverage": "~2.2.0", "karma-jasmine": "~5.1.0", "karma-jasmine-html-reporter": "~2.1.0", "typescript": "~5.2.2" } }
解决步骤
修正MatDialogRef泛型类型
对话框组件中MatDialogRef的泛型参数错误,应指向当前组件而非LoginModalComponent:private readonly _dialogRef: MatDialogRef<UsersCrudModalComponent>,确认MAT_DIALOG_DATA导入正确性
确保从@angular/material/dialog正确导入令牌:import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';恢复experimentalDecorators配置
将tsconfig.json中experimentalDecorators改回true,Angular依赖装饰器功能,关闭会引发更多兼容性问题。修复父组件find方法逻辑错误
父组件中find回调使用了赋值运算符=,应改为严格比较运算符===:const user: IUser | undefined = this._users.find((f: IUser) => f.uuid === uuid);
完成以上修改后重启项目,相关注入错误即可解决。
内容的提问来源于stack exchange,提问作者Lira Lunaris

