web-dev-qa-db-ja.com

Angularで、遅延ロードされたモジュール内のパスに直接移動するにはどうすればよいですか?

ログインして登録するための2つの最上位パスが必要です。

auth/log-inおよびauth/register

ただし、authコンポーネントは別のモジュールにあります。特に要求されない限りロードされないため、これは良いモジュールです。

export const routes: Route[] = [
  { path: 'log-in',   loadChildren: './auth-module/auth.module#AuthModule'},
  { path: 'register', loadChildren: './auth-module/auth.module#AuthModule'}
];

必要なルートを定義するときに、どのように指定できますかlog-inへのパスlog-in path inside遅延ロードされたAuthModule、およびregister path to register path inside遅延ロードモジュール?

14
CodyBugstein
export const routes: Route[] = [
  { path: 'log-in',   loadChildren: './auth-module/auth.module#AuthModule'},
  { path: 'register', loadChildren: './auth-module/auth.module#AuthModule'}
];

私はそれが可能ではないとは言いません。リダイレクトによって読み込まれるLazy loadingモジュール。これの意味は:

  • log-inのナビゲートを開始します。
  • 遅延読み込みモジュールが読み込みを開始します
  • 正常に読み込まれた後、URLはsomePath/log-inになります
  • それで、次は何ですか?ここでリダイレクトプロセスが開始されます。したがって、各遅延ロードモジュールのrouting.tsには、次のようにエントリポイントパスを含める必要があります。

    {
       path: '',
       redirectTo: 'somePath/ChildPath' // or component: SomeComponent
    }
    

それがナビゲートしたルートに関係なく、それが遅延モジュールの場合は、エントリパスを見つけようとします。あなたのケースでは、同じモジュールをロードする2つのルートだけでなく、同じエントリルートパス(path: '')も参照しています。

それらを本当に分割したい場合は、それらを異なるモジュールに割り当てる必要があります。

export const routes: Route[] = [
  { path: 'log-in',   loadChildren: './auth-module/someModule#someModule'},
  { path: 'register', loadChildren: './auth-module/auth.module#AuthModule'}
];

some-module.routing.ts:

{
    path: '',
    component: LoginComponent,

},

アップデート29.04.18。もう1つのコンポーネントを持つ単純なソリューション

解決策は、現在のurlに応じて、他のコンポーネントのrendererとして機能する追加コンポーネントを作成することです。

app-routing.module:

const appRoutes: Routes = [
 ...

  {
    path: 'admin',
    loadChildren: 'app/admin/admin.module#AdminModule',

  },
  {
    path: 'login',
    loadChildren: 'app/admin/admin.module#AdminModule',

  },
  {
    path: 'crisis-center',
    loadChildren: 'app/crisis-center/crisis-center.module#CrisisCenterModule',
    // data: { preload: true }
  },
  { path: '', redirectTo: '/superheroes', pathMatch: 'full' },
  { path: '**', component: PageNotFoundComponent }
];

admin.module作成rendererコンポーネント

central.component.ts:

...

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

  currentComponent: LoginComponent | AdminComponent;

  constructor(public router: Router, public activatedRoute: ActivatedRoute) { }

  ngOnInit() {
    if (this.router.url === '/login') {
      this.currentComponent = LoginComponent;
    } else {
      this.currentComponent = AdminComponent;
    }
  }
}

central.component.template:

<ng-container *ngComponentOutlet="currentComponent"></ng-container>

ご覧のとおり、中央のコンポーネントは、URLパスに応じてコンポーネントを動的にレンダリングします。

NgComponentOutlet を使用した宣言的アプローチメソッドを使用したレンダリング

命令型および宣言型のアプローチの詳細: https://stackoverflow.com/a/49840700/5677886

StackBlitzデモ

6
Yerkon

これまでは、投稿で意図したとおりにルートを構成することはできません。ルーターのロギングを有効にすると確認できます。モジュールのパス(ログイン、レジスター)が消費され、モジュールのルーティングでは_''_が残ります。これは、2つの異なるコンポーネントに一致させることはできません。

たとえそれがそれほど良くなくても、古いブラウザでどのように/どのように機能するかわからない場合でも、これを達成できます。

あなたの_app.module.ts_

_const APP_ROUTES: Routes = [
    { path: 'login', redirectTo: 'auth/login', pathMatch: 'full' },
    { path: 'register', redirectTo: 'auth/register', pathMatch: 'full' },
    { path: 'auth', loadChildren: 'app/auth/auth.module#AuthModule', pathMatch: 'prefix'},
];

@NgModule( {
    declarations: [
        AppComponent
    ],
    imports: [
        BrowserModule,
        RouterModule,
        RouterModule.forRoot(APP_ROUTES)
    ],
    providers: [
    ],
    bootstrap: [AppComponent]
})
export class AppModule { }
_

_auth.module.ts_は次のようになります

_const ROUTES: Routes = [
    { path: 'login', component: LoginComponent, pathMatch: 'full' },
    { path: 'register', component: RegisterComponent, pathMatch: 'full' }
];

@NgModule( {
    imports: [
        CommonModule,
        RouterModule.forChild( ROUTES )
    ],
    declarations: [
        LoginComponent,
        RegisterComponent
    ]   
} )
export class AuthModule { }
_

その後、_<a routerLink="login">Login</a>_でルートにアクセスでき、_router.navigate_でも機能します。残念ながら、これにより、クライアントが_auth/login_のみを呼び出した場合でも、ブラウザーのURLに_auth/register_または_/login_が残ります。

_window.history_にエントリを作成することで、この問題を修正できます。これは、私がきれいにしないように言ったように、コンポーネントコンストラクタで行う必要があります。コンポーネントのwindow.history.pushState('register', 'Register', 'register');またはwindow.history.pushState('login', 'Login', 'login');は、ブラウザーのURLに_/login_および_/register_を付けたままにします。

最善の方法は、angularルーターをこの機能で拡張し、カスタムルーターとして使用することですが、そのために本当にそれに入る必要があり、次の更新では、ねじ込まれる。

多分これはあなたを助ける

宜しくお願いします

7
Fussel

App-routingモジュールは、機能モジュールのルートのプレフィックス(またはプレフィックス)を付けることができます。 /authのようなルートプレフィックスが必要ない場合は、遅延読み込みを使用するか、いいえ)を使用して、次のようなことができます。

app-routing.module.ts:

  {
    path:             '',
    canActivate:      [AuthGuard],
    canActivateChild: [AuthGuard],
    children:         [
      {
        path:      '',
        component: HomeComponent,
      },
      {
        path:         '',
        loadChildren: 'app/auth/auth.module#AuthModule',
      },
      {
        path:      'settings',
        component: SettingsComponent,
      },
    ],
  },

遅延ロードされたモジュールの最上位ルートは静的である必要はなく、次のような構成にすることができます。

auth-routing.module.ts:

const routes: Routes = [
  {
    path:      ':pageName',
    component: AuthComponent,
    resolve:   {
      pageInfo: AuthResolver,
    },
    children:  [
      {
        path:      'login',
        component: LoginComponent,
      },
      {
        path:      'register',
        component: RegisterComponent,
      },
    ],
  },
];
1