子模块组件的自定义RouteReuseStrategy

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

角度v-15.2.7

我不希望重新路由后出现松散的表单数据。所以我正在尝试实施RouteReuseStrategy。 我的应用程序结构略有不同。我的组件位于模块内(例如 customer-routing.module.ts),但路由是在根级别定义的(即在 app.routing.module.ts 中)。

客户路由.module.ts

    import { NgModule } from '@angular/core';
    import { RouterModule, Routes } from '@angular/router';
    
    const routes: Routes = [];
    
    @NgModule({
      imports: [RouterModule.forChild(routes)],
      exports: [RouterModule]
    })
    export class CustomerRoutingModule { }

app-routing.module.ts

import { Component, NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { AppComponent } from './app.component';
import { NoaccessComponent } from './core/components/noaccess/noaccess.component';
import { AuthGuard } from './core/authguard/auth.guard';
import { CustomerCreationComponent } from './modules/customer/components/customer-creation/customer-creation.component';
import { CustomerViewComponent } from './modules/customer/components/customer-view/customer-view.component';

const routes: Routes = [
  {
    path: 'master',
    canActivate: [AuthGuard],
    component: AppComponent
  },
  {
    path: 'create/:email/:phnNumber',
    canActivate: [AuthGuard],
    component:CustomerCreationComponent,
       data: {
       shouldReuseRoute: true,
       reuseRoutesFrom: ['master', 'view/:email/:phnNumber']
    }
  },
  {
    path: 'view/:email/:phnNumber',
    canActivate: [AuthGuard],
    component:CustomerViewComponent
  },
  {
    path:'accessdenied',
    component: NoaccessComponent
  },
];

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

app.module.ts

import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { MaterialModule } from './modules/shared/material.module';
import { HeaderComponent } from './core/components/header/header.component';
import { FooterComponent } from './core/components/footer/footer.component';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { NoaccessComponent } from './core/components/noaccess/noaccess.component';
import { CustomerModule } from './modules/customer/customer.module';
import { RouteReuseStrategy } from '@angular/router';
import { CustomerRouteReuseStrategy } from './router-strategy';

@NgModule({
  declarations: [
    AppComponent,
    HeaderComponent,
    FooterComponent,
    NoaccessComponent,  
  ],
  imports: [
    AppRoutingModule,
    MaterialModule,
    HttpClientModule,
    CustomerModule,
  ],
  providers: [
    {
      provide: RouteReuseStrategy,
      useClass: CustomerRouteReuseStrategy
    }
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

路由器策略.ts

import {RouteReuseStrategy,ActivatedRouteSnapshot,DetachedRouteHandle,} from '@angular/router';
  
  export class CalllogRouteReuseStrategy implements RouteReuseStrategy {
    private routeLeftFrom: string | undefined;
    private handlers: { [key: string]: DetachedRouteHandle } = {};
  
    shouldDetach(route: ActivatedRouteSnapshot): boolean {
      this.routeLeftFrom = route.routeConfig!.path;
        return route.data['shouldReuseRoute'] || false;
    }

    store(route: ActivatedRouteSnapshot, handler: DetachedRouteHandle): void {
      console.log('[router-reuse] storing handler');
      if (handler) {
        this.handlers[this.getUrl(route)] = handler;
      }
    }

    shouldAttach(route: ActivatedRouteSnapshot): boolean {
      var wasRoutePreviouslyDetached = !!this.handlers[route.url.join('/') || route.parent!.url.join('/')];
        if (wasRoutePreviouslyDetached) {
            var reuseRouteFromVerified = route.data['reuseRoutesFrom'].indexOf(this.routeLeftFrom) > -1;

            if (reuseRouteFromVerified) {

                return true;
            }
        }
        return false;
    }

    retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle | null {
        if (!route.routeConfig || route.routeConfig.loadChildren) {
          return null;
        }
      
        return this.handlers[this.getUrl(route)];
      }      
  
    shouldReuseRoute(future: ActivatedRouteSnapshot,current: ActivatedRouteSnapshot): boolean {
      let reUseUrl = false;
  
      if (future.routeConfig) {
        if (future.routeConfig.data) {
          reUseUrl = future.routeConfig.data['reuse'];
        }
      }
      const defaultReuse = future.routeConfig === current.routeConfig;
  
      return reUseUrl || defaultReuse;
    }
  
    getUrl(route: ActivatedRouteSnapshot): string {
        if (route.routeConfig) {
          const url = route.routeConfig.path;
          console.log('[router-reuse] returning url', url);
      
          return url as string; 
        }
      
        throw new Error('Route configuration is missing for the provided route.');
    }
  }


  

问题是:没有参数的重新路由器工作正常。但是有了参数,表单数据就会消失

javascript angular typescript angular-routing angular-forms
1个回答
0
投票

您可以通过使用根级别注入服务来实现这一点。在组件 ngDestroy 事件中,您可以将对象保存在服务变量中,当重新访问页面时,您可以从服务中读取它。

  1. 创建根级服务

    import { Injectable } from '@angular/core';
    
    @Injectable()
    export class AppService {
       private formData;
    
      setFormData(formData) {
        this.formData = formData;
      }
    
      getFormData() {
        return this.formData;
     }
    }
    
  2. 在组件销毁事件上将数据设置为服务变量

     ngOnDestroy() {
         this.appService.setFormData(this.contactForm.getRawValue());
     }
    
  3. 在 ngOnInit 事件上从服务设置表单

     setFormData() {
        const data = this.appService.getFormData();
        if (data) {
           this.contactForm.get('name').setValue(data.name);
           this.contactForm.get('title').setValue(data.title.title);
        } else {
          // initialise contact form
        }
     }
    

看看这个 -
https://stackblitz.com/edit/angular-material-reactive-forms-validation-rqhd6v

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