导航在 Angular 10 中无法启动

问题描述 投票:0回答:3

我是 Angular 新手,参考以下问题,但没有任何适合我的情况的解决方案。

我在路由和导航时收到以下错误。

  NullInjectorError: No provider for MatDialogRef!
NullInjectorError: R3InjectorError(UserModule)[MatDialogRef -> MatDialogRef -> MatDialogRef -> MatDialogRef]:
  NullInjectorError: No provider for MatDialogRef!
    at NullInjector.get (core.js:1013:1)
    at R3Injector.get (core.js:11130:1)
    at R3Injector.get (core.js:11130:1)
    at R3Injector.get (core.js:11130:1)
    at NgModuleRef$1.get (core.js:24252:1)
    at R3Injector.get (core.js:11130:1)
    at NgModuleRef$1.get (core.js:24252:1)
    at Object.get (core.js:23956:1)
    at getOrCreateInjectable (core.js:4169:1)
    at Module.ɵɵdirectiveInject (core.js:14660:1)
    at resolvePromise (zone-evergreen.js:798:1)
    at resolvePromise (zone-evergreen.js:750:1)
    at zone-evergreen.js:860:1
    at ZoneDelegate.invokeTask (zone-evergreen.js:399:1)
    at Object.onInvokeTask (core.js:27483:1)
    at ZoneDelegate.invokeTask (zone-evergreen.js:398:1)
    at Zone.runTask (zone-evergreen.js:167:1)
    at drainMicroTaskQueue (zone-evergreen.js:569:1)
    at invokeTask (zone-evergreen.js:484:1)
    at ZoneTask.invoke (zone-evergreen.js:469:1)

文件app.routing.module.ts

import { NgModule } from "@angular/core";
import { Routes, RouterModule, PreloadAllModules } from "@angular/router";
import { LocationStrategy, HashLocationStrategy } from "@angular/common";
import { AuthGuard } from "./guard/auth.guard";
import { RouterDeactivateService } from "./services/router-deactivate.service";
import { ChangePasswordComponent } from './user/change-password/change-password.component';
/*Main Routing module wise with security check, we have written security check
under DI [AuthGuard], if user is log in then they may move from one module to another module.
*/

export const APP_ROUTES: Routes = [
  {
    path: "",
    children: [
      { path: "", loadChildren: () => import('./user/user.module').then(m => m.UserModule) },
      {
        path: "customer",
        canActivate: [AuthGuard],
        loadChildren: () => import('./customer/customer.module').then(m => m.CustomerModule)
      },
      {
        path: "report",
        canActivate: [AuthGuard],
        loadChildren: () => import('./report/report.module').then(m => m.ReportModule)
      },
      {
        path: "policy",
        canActivate: [AuthGuard],
        canDeactivate: [RouterDeactivateService],
        loadChildren: () => import('./policy/policy.module').then(m => m.PolicyModule)
      },
      {
        path: "claim",
        canActivate: [AuthGuard],
        loadChildren: () => import('./claim/claim.module').then(m => m.ClaimModule)
      },
      {
        path: "mainClaim",
        canActivate: [AuthGuard],
        loadChildren: () => import('./mainClaim/mainClaim.module').then(m => m.MainClaimModule)
      },
      {
        path: "admin",
        canActivate: [AuthGuard],
        loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule)
      },
      {
        path: "general-report",
        canActivate: [AuthGuard],
        loadChildren:
          () => import('./general-module/general-module.module').then(m => m.GeneralModuleModule)
      },
      {
        path: "products",
        canActivate: [AuthGuard],
        loadChildren: () => import('./products/products.module').then(m => m.ProductsModule)
      }
    ]
  }
];

@NgModule({
  imports: [
    RouterModule.forRoot(APP_ROUTES, {
      enableTracing: false,
      preloadingStrategy: PreloadAllModules
    })
  ],
  exports: [RouterModule],
  providers: [{ provide: LocationStrategy, useClass: HashLocationStrategy }]
})
export class AppRoutingModule {}

文件app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { AppRoutingModule } from './app.routing.module';
import { AuthGuard } from './guard/auth.guard';
import { RouterDeactivateService } from './services/router-deactivate.service';
import { DataSharingService } from './shared/services/dataSharing.service';
import { HttpClientModule } from '@angular/common/http';
import { AuthheaderService } from './shared/services/auth-header.service';
import { UploadDocumentService } from './claim/upload-document/upload-document.service';
import { ToastrModule } from 'ngx-toastr';

@NgModule({
  declarations: [
    AppComponent

  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    AppRoutingModule,
    HttpClientModule,
    ToastrModule.forRoot({
      positionClass: 'toast-bottom-right'
    })
  ],
  providers: [
    AuthGuard,
    RouterDeactivateService,
    DataSharingService,
    AuthheaderService,
    UploadDocumentService
  ],
  bootstrap: [
    AppComponent
  ]
})
export class AppModule { }

文件user.routing.module.ts

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { LoginComponent } from "./login/login.component";
import { ChangePasswordComponent } from './change-password/change-password.component';
import { ForgotPasswordComponent } from './forgot-password/forgot-password.component';

const USER_ROUTES: Routes = [
  { path: '', component: LoginComponent },
  { path: 'changePassword', component: ChangePasswordComponent },
  { path: 'forgotPassword', component: ChangePasswordComponent },
  ];

@NgModule({
    imports: [RouterModule.forChild(USER_ROUTES)],
    exports: [RouterModule]
})

export class UserRoutingModule { }
export const routingComponent = [ChangePasswordComponent, ForgotPasswordComponent, LoginComponent]

文件user.module.ts

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule } from "@angular/router";
import { HttpClientModule } from '@angular/common/http';
import { UserRoutingModule, routingComponent } from "./user.routing.module";
import { NgxSpinnerModule } from 'ngx-spinner';
import { MatDialogModule } from "@angular/material/dialog";
import { MatPasswordStrengthModule } from '@angular-material-extensions/password-strength';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatSelectModule } from '@angular/material/select';
import { MatCardModule } from '@angular/material/card';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { MatInputModule } from '@angular/material/input';
import { MatFormFieldModule } from '@angular/material/form-field';
import { FlexLayoutModule } from '@angular/flex-layout';

import { FormsModule, ReactiveFormsModule } from "@angular/forms";
import { LoginService } from "./user.service";
@NgModule({
  imports: [
    CommonModule,
    RouterModule,
    UserRoutingModule,
    HttpClientModule,
    MatButtonModule,
    MatCheckboxModule,
    MatCardModule,
    MatFormFieldModule,
    MatSelectModule,
    MatInputModule,
    MatIconModule,
    FormsModule,
    MatProgressSpinnerModule,
    ReactiveFormsModule,
    NgxSpinnerModule,
    MatDialogModule,
    FlexLayoutModule,
    MatPasswordStrengthModule
  ],
  entryComponents: [
    routingComponent
  ],
  declarations: [
    routingComponent
  ],
  providers: [
    LoginService
  ]
})
export class UserModule { }

文件package.json

{
  "name": "<xyz>",
  "version": "0.0.0",
  "license": "<xqw>",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "10.2.1",
    "@angular/cdk": "^10.2.6",
    "@angular/common": "10.2.1",
    "@angular/compiler": "10.2.1",
    "@angular/core": "10.2.1",
    "@angular/flex-layout": "^10.0.0-beta.32",
    "@angular/forms": "10.2.1",
    "@angular/material": "^10.2.6",
    "@angular/platform-browser": "10.2.1",
    "@angular/platform-browser-dynamic": "10.2.1",
    "@angular/router": "10.2.1",
    "@ngui/datetime-picker": "^0.16.2",
    "@angular-material-extensions/password-strength": "^7.0.0",
    "angular7-csv": "^0.2.12",
    "classlist.js": "^1.1.20150312",
    "core-js": "^2.6.11",
    "hammerjs": "^2.0.8",
    "less": "^3.12.2",
    "moment": "^2.29.1",
    "ng-pick-datetime": "^7.0.0",
    "ng2-eonasdan-datetimepicker": "^0.1.4",
    "ngx-date-time-picker": "^1.1.6",
    "ngx-order-pipe": "^2.1.1",
    "ngx-pagination": "^5.0.0",
    "ngx-spinner": "^10.0.1",
    "ngx-uploader-directive": "^1.2.5",
    "rxjs": "^6.6.3",
    "scss": "^0.2.4",
    "tslib": "^2.0.0",
    "web-animations-js": "^2.3.2",
    "zone.js": "^0.10.3",
    "ngx-toastr": "^13.2.1"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~0.1002.0",
    "@angular/cli": "10.2.0",
    "@angular/compiler-cli": "10.2.1",
    "@angular/language-service": "10.2.1",
    "@types/jasmine": "~3.6.0",
    "@types/jasminewd2": "~2.0.8",
    "@types/node": "^12.19.3",
    "codelyzer": "^5.1.2",
    "https-proxy-agent": "^5.0.0",
    "jasmine-core": "~3.5.0",
    "jasmine-spec-reporter": "~5.0.0",
    "karma": "~5.0.0",
    "karma-chrome-launcher": "~3.1.0",
    "karma-coverage-istanbul-reporter": "~3.0.2",
    "karma-jasmine": "~4.0.0",
    "karma-jasmine-html-reporter": "^1.5.0",
    "node-sass": "^4.14.1",
    "protractor": "~7.0.0",
    "ts-node": "~9.0.0",
    "tslint": "~6.1.0",
    "typescript": "4.0.5"
  }
}

我同时使用

this.router.navigate(['changePassword']);
this.router.navigateByUrl('/changePassword');
,但没有一个在导航。

下面是我的代码结构

更新部分问题

现在注入错误已解决,但我仍然无法导航到changePassword 组件。

angular angularjs typescript angular-routing
3个回答
0
投票

您正在使用 Observable,这可能会在导航到组件时产生问题。您可以创建一个新方法,该方法会在您的订阅成功结束时完成或承诺做出响应。因此,在下面的代码中,您可以在您的情况下使用它:

logout() {
    new Promise((resolve, reject) => {
        this.http.delete(this.baseUrl + url, { headers: this.headers() })
            .map((res: IResponse) => {
              var json = res.json();
              json.headers = res.headers;
              return json;
            })
            .subscribe(data => {
              //DO SOMETHING, THEN ----
              resolve(data);
            }, error => reject(error));
    }).then(response => this.router.navigate(['LandingPage']));
}

0
投票

如果当您在点击处理程序中添加 .navigate 代码时 Angular 子路由工作正常,但在放置在 API 成功回调中时它不起作用,则可能是由于计时问题。

当您在 API 成功回调中使用 .navigate 导航到不同的路线时,Angular 可能正在更新视图或执行其他异步任务。如果在 Angular 完成当前摘要周期之前在回调中触发导航代码,则可能会导致意外行为。

为了确保 API 成功回调中的导航代码一致工作,您可以使用 Angular 的 NgZone 服务。 NgZone 服务允许您在特定区域中运行代码,它可以帮助避免与异步执行相关的问题。

以下是如何修改代码以使用 NgZone:

将 NgZone 服务注入到您的组件中:

import { Component, NgZone } from '@angular/core';

@Component({
  // component configuration
})
export class YourComponent {
  constructor(private ngZone: NgZone) {}

  // Other component methods and properties
}

使用 ngZone.run() 在 NgZone 中运行导航代码:

import { Component, NgZone } from '@angular/core';
import { YourAPIService } from 'path/to/your-api.service';
import { Router } from '@angular/router';

@Component({
  // component configuration
})
export class YourComponent {
  constructor(private ngZone: NgZone, private apiService: YourAPIService, private router: Router) {}

  // Your API call method
  makeAPICall() {
    this.apiService.makeAPIRequest().subscribe(
      (response) => {
        // Your API success callback
        // Run the navigation code within NgZone
        this.ngZone.run(() => {
          this.router.navigate(['/your-child-route']);
        });
      },
      (error) => {
        // Your error handling code
      }
    );
  }
}

通过使用 ngZone.run(),导航代码将在 Angular 区域内执行,确保它在应用程序的上下文中得到正确处理,并且导航工作一致。

请记住,NgZone服务是处理 Angular 中异步代码的强大工具。但是,应谨慎使用它,并且仅在必要时使用它,因为如果过度使用它可能会影响性能。在大多数情况下,Angular 的更改检测应该负责适当地更新视图。


0
投票

您是否添加了

import { Router} from '@angular/router';
并将其添加到了

constructor (private router: Router) {

}

要导航到更改密码组件的组件 TypeScript 文件。

© www.soinside.com 2019 - 2024. All rights reserved.