2016-11-04 63 views
0

我想了解custom route preloading如何在angular2中工作。但我只是无法让它工作在第一位。Angular2 PreloadingStrategy无法正常工作

这里是我的代码

custom.preloading-strategy.ts

export class CustomPreloadingStrategy implements PreloadingStrategy { 
    preload(route: Route, fn:() => Observable<any>): Observable<any> { 
     console.log("Preloading..."); 
     return Observable.of(true).delay(1000).flatMap(_ => fn()); 
    } 
} 

app.routes.ts

const appRoutes: Routes = [ 
    { 
     path: '', 
     redirectTo: 'home', 
     pathMatch: 'full', 
     data: { 
      preload: true 
     } 
    }, 
    { 
     path: 'home', 
     component: HomeComponent, 
     data: { 
      preload: true 
     } 
    } 
]; 

export const appRoutingProviders: any[] = [ 
    CustomPreloadingStrategy 
]; 

export const routeComponents: any[] = [ 
    HomeComponent 
]; 

export const routing = RouterModule.forRoot(appRoutes, { 
    preloadingStrategy: CustomPreloadingStrategy, 
    useHash: true 
}); 

app.module.ts

@NgModule({ 
    bootstrap: [AppComponent], 
    providers: [appRoutingProviders, appServices], 
    imports: [ 
     BrowserModule, 
     FormsModule, 
     HttpModule, 
     routing 
    ], 
    declarations: [ 
     AppComponent, 
     SharedComponents, 
     appDirectives, 
     routeComponents, 
     NewsMediaListComponent 
    ], 
    entryComponents: [AppComponent] 
}) 

的DEP

"@angular/common": "2.1.2", 
"@angular/compiler": "2.1.2", 
"@angular/core": "2.1.2", 
"@angular/forms": "2.1.2", 
"@angular/http": "2.1.2", 
"@angular/platform-browser": "2.1.2", 
"@angular/platform-browser-dynamic": "2.1.2", 
"@angular/router": "3.1.2", 
"rxjs": "5.0.0-rc.1", 

然而,有没有错误或任何在日志中。我不知道我在这里错过了什么。

回答

1

延迟加载仅适用于模块。

因此,如果您只在路线中使用HomeComponent作为组件,则此功能无效。相反,组件的属性,你应该创建自己的模块为HomeComponent,在该路由使用loadChildrenapp.routing.ts):

{ 
    path: 'home', 
    loadChildren: './../home/home.module#HomeModule', 
    data: { preload: true } 
} 

在一个单独的文件创建另一个模块(home.module .TS):

import { NgModule, Component } from '@angular/core'; 
import { HomeComponent } from './home.component'; 
import { routing } from './home.routing'; 

@NgModule({ 
    imports: [ 
     routing 
    ], 
    declarations: [ 
     HomeComponent 
    ] 
}) 
export class HomeModule { } 

,创造了此组件的路由文件(home.routing.ts):

import { HomeComponent } from './home.component'; 
import { RouterModule, Routes } from '@angular/router'; 
import { ModuleWithProviders } from '@angular/core'; 

const homeRoutes: Routes = [ 
    { path: '', component: HomeComponent } 
] 

export const routing: ModuleWithProviders = RouterModule.forChild(
    homeRoutes 
); 

data: { preload: true }只能用于具有属性loadChildren的路由。你仍然可以为任何其他路由设置数据属性,但这与延迟加载本身无关。

您应该阅读关于延迟加载模块的精心编写的article of Victor Savkin


更新答案: 我也看到data: { preload: true }是行不通的,因为你需要处理这个在您的自定义预加载的策略是这样的:

export class SelectedPreloadingStrategy implements PreloadingStrategy { 
    preload(route: Route, load: Function): Observable<any> { 
     return route.data && route.data['preload'] ? load() : Observable.of(null); 
    } 
} 

什么你还需要做的是导出此预加载策略,以便在您的提供程序阵列中的app.module中使用它:

in app.routing。如果寄托都正确,你编译

providers: [ 
    ... 
    APP_ROUTES_MODULE_PROVIDER 
], 

:TS

export const APP_ROUTES_MODULE_PROVIDER = [SelectedPreloadingStrategy]; 

并导入它app.module.ts

import { routing, APP_ROUTES_MODULE_PROVIDER } from './app.routing'; 

@NgModule -providers阵列路由到您的应用程序中的延迟加载模块,您应该检查开发工具的Network-Tab你会看到路由器只有在导航到模块后才加载模块。

+0

我已经从那篇文章中得到了实例。然而,我尝试了你的确切的解决方案,以及使用模块和组件的另一个名称('TestComponent'和'TestModule'),但我仍然没有得到我的'console.log'。无论我在我的'appRoutes'中使用'component'还是'loadChildren',这个行为都是一样的,调试器在'preload'行中断开并且不执行里面的脚本。 – choz

+0

您编辑的解决方案中的差异仅仅是将'PreloadingStrategy'导入到应用程序路径'提供程序'中。实际上,在我原来的问题中,我已经将它包含在内,并且还将其包含在我的路由器模块'RouterModule.forRoot(appRoutes,{preloadingStrategy:CustomPreloadingStrategy,useHash:true});'中。这还没有为我工作。 – choz

1

您希望以与PreloadAllModules模块策略相同的方式定义您的策略,该策略只会预载所选模块。所以,你应该使用的正确loadChildren在路线为:

export const appRoutes: Routes = [ 
    { 
     path: '', 
     redirectTo: 'home', 
     pathMatch: 'full' 
    }, 
    { 
     path: 'home', 
     loadChildren: './app/home.module#HomeModule', 
     data: { 
      preload: true 
     } 
    } 
]; 

另外,请你看看Custom Pre-loading一次在here创建一个自定义的预加载策略的例子。