NgModuleFactoryLoader.load()找不到模块



请参阅此处的项目结构,我创建了一个包含多个惰性加载嵌套模块的项目。

  1. 在应用程序启动时加载AppModule
  2. 当用户单击登录按钮时,将加载LoginModule
  3. 如果用户存在,即如果登录成功,则作为AppModule的另一个功能模块的IntegratedPntsModule应该从login-routing.module.ts延迟加载;pmntButton"'但那不是我想要的

我在这里的要求是有条件地加载组件login.component.ts中所示的功能子模块,当用户登录失败时,应该将其导航到登录(由于登录模块已经延迟加载,所以工作正常(,当登录成功时,用户应该导航到IntegratedPntsModule中的IntegratedPaymentsComponent(这没有发生(。

  1. this.router.navigation(['integratedPayments'](;--正在给出"未捕获(承诺中(:错误:无法匹配任何路线"integratedPayments">

  2. 我甚至尝试使用NgModuleFactoryLoader.load((的load((方法加载IntegratedPntsModule,该方法给出了"找不到模块错误">

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 { }

由于integratedPayments路由是login路由的子级,因此应使用: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选项。将CCD_ 9作为CCD_。

这意味着您可以通过登录组件使其与this.router.navigate(['integratedPayments']);一起工作。

您必须首先在登录组件中注入ActivatedRoute,然后将relativeTo选项添加到route.navigate:

this.router.navigate(['integratedPayments'], { relativeTo: this.route });

最新更新