NgModuleFactoryLoader.load() не может найти модуль

Пожалуйста, обратитесь к моей структуре проекта здесь. Я создал проект с несколькими отложенными вложенными модулями.

  1. При запуске приложения загружается AppModule
  2. Когда пользователь нажимает кнопку входа в систему, загружается LoginModule
  3. Если пользователь существует, т. Е. При успешном входе в систему, IntegratedPmntsModule, который является еще одним функциональным модулем AppModule, следует лениво загружать из login-routing.module.ts. Он отлично загружает IntegratedPmntsModule с помощью 'button routerLink=' IntegratePayments' class="pmntButton"', но это не то, что я хочу.

Мое требование здесь состоит в том, чтобы условно загрузить функциональный дочерний модуль, как показано в компоненте login.component.ts, когда логин пользователя не удался, он должен перейти к логину (он работает нормально, так как LoginModule уже загружен лениво) и когда логин успешен пользователь должен перейти к IntegratedPaymentsComponent, присутствующему в IntegratedPmntsModule (чего не происходит).

  1. this.router.navigate (['IntegratedPayments']); - выдает сообщение "Не поймано (в обещании): Ошибка: не удается сопоставить ни один маршрут" IntegratedPayments "

  2. Я даже попытался загрузить IntegratedPmntsModule с помощью метода load() NgModuleFactoryLoader.load(), который дает ошибку "модуль не найден"

login.component.ts

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {

  loginFormGroup: FormGroup;
  customerModel:CustomerLoginModel = new CustomerLoginModel();
  userExist: Boolean = true;

  constructor(private loginService: LoginService, private router: Router, private readonly loader: NgModuleFactoryLoader) { }

  ngOnInit(): void {
    this.loginFormGroup = new FormGroup({
      customerId: new FormControl('', [Validators.required,Validators.maxLength(20),Validators.pattern('^[a-zA-Z0-9]+([._]?[a-zA-Z0-9]+)*$')]),
      password: new FormControl('', [Validators.required, Validators.maxLength(15)])
    })
  }
  submitLoginForm(formGroup: FormGroup): any{
   
   this.customerModel.setCustomerId(formGroup.value.customerId);
   this.customerModel.setPassword(formGroup.value.password);
   this.loginService.authenticateCustomer(this.customerModel).subscribe(
     response=>{
       this.userExist=response},
      error=>{
        console.log(error)
      }
    );
      if(this.userExist){
          //this.loader.load('./app/integrate-pmnts-module/integrate-pmnts.module#IntegratePmntsModule').
          //then(factory =>this.router.navigate(['integratedPayments']));
          this.router.navigate(['integratedPayments']);
      }
      else
        this.router.navigate(['login']);
  }

}

app-routing.module.ts

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { LoginauthGuard } from './login/loginauth.guard';


const routes: Routes = [
 
  {
    path: 'login',
    loadChildren: () => import('./login/login.module').then(mdule=>mdule.LoginModule),
  },
  
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

login-routing.module.ts


const routes: Routes = [
  {
    path: '',
    component: LoginComponent,
    //canDeactivate: [LoginauthGuard]
  },
  {
    path: 'integratedPayments',
    loadChildren: () => import('../integrate-pmnts-module/integrate-pmnts.module').then(mdule=>mdule.IntegratePmntsModule)
  }
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
export class LoginRoutingModule { 

}

login.component.html


<html>
    <form [formGroup]="loginFormGroup" (ngSubmit)="submitLoginForm(loginFormGroup)"> 
            Customer Id:<input type="text" formControlName="customerId" placeholder="Enter Customer ID"><br><br>
            Password: <input type="password" formControlName="password" placeholder="Enter Password"><br><br>
            <div *ngIf='!userExist'>
                Please enter valid credentials!
            </div><br><br>
        <button class="pmntButton">Login</button>
    </form>
</html>

integratepayments-routing.module.ts


const routes: Routes = [
    {
        path: '',
        component: IntegratedPaymentsComponent
    },
    {
      path: 'eftPaymentsPage',
      loadChildren: () => import('src/app/integrate-pmnts-module/eft-payments-module/eft-payments-module').then(mod=>mod.EftPaymentsModuleModule)
    }
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
export class IntegratedPaymentsRoutingModule { }

1 ответ

Решение

Поскольку integratedPaymentsМаршрут является ребенком изlogin route следует использовать: this.router.navigateByUrl('login/integratedPayments').

Однако это может не работать, потому что маршруты из login-routing.module.ts определяются следующим образом:

const routes: Routes = [
  {
    path: '',
    component: LoginComponent,
    //canDeactivate: [LoginauthGuard]
  },
  {
    path: 'integratedPayments',
    loadChildren: () => import('../integrate-pmnts-module/integrate-pmnts.module').then(mdule=>mdule.IntegratePmntsModule)
  }
];

что означает, что первый маршрут (path: '') всегда будет соответствовать. Что вы можете сделать, чтобы этого избежать, так это добавитьpathMatch: 'full' вариант:

const routes: Routes = [
  {
    path: '',
    component: LoginComponent,
    pathMatch: 'full'
  },
  {
    path: 'integratedPayments',
    loadChildren: () => import('../integrate-pmnts-module/integrate-pmnts.module').then(mdule=>mdule.IntegratePmntsModule)
  }
];

отлично с 'button routerLink=' IntegratePayments' class="pmntButton"'

это из-за того, как RouterLink директива работает внутри.

Давайте посмотрим, что произойдет, когда вы нажмете кнопку с этой директивой:

@HostListener('click')
  onClick(): boolean {
    const extras = {
      skipLocationChange: attrBoolValue(this.skipLocationChange),
      replaceUrl: attrBoolValue(this.replaceUrl),
      state: this.state,
    };
    this.router.navigateByUrl(this.urlTree, extras);
    return true;
  }

  get urlTree(): UrlTree {
    return this.router.createUrlTree(this.commands, {
      relativeTo: this.route, // !
      queryParams: this.queryParams,
      fragment: this.fragment,
      preserveQueryParams: attrBoolValue(this.preserve),
      queryParamsHandling: this.queryParamsHandling,
      preserveFragment: attrBoolValue(this.preserveFragment),
    });
  }

как видите, он использует relativeTo вариант. this.route вводится как private route: ActivatedRoute.

Это означает, что вы можете заставить его работать с this.router.navigate(['integratedPayments']); от вашего компонента входа в систему.

Вам нужно сначала ввести ActivatedRoute внутри компонента входа в систему, а затем добавьте relativeTo возможность route.navigate:

this.router.navigate(['integratedPayments'], { relativeTo: this.route });
Другие вопросы по тегам