2016-11-04 2 views
0

Я пытаюсь понять, как это custom route preloading работает в угловом2. Но я просто не могу заставить его работать в первую очередь.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] 
}) 

DEPS

"@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

Lazy loading работает только с модулями.

Так что это не сработает, если вы используете только HomeComponent в своем маршруте в качестве компонента. Вместо компонента-атрибута, вы должны создать свой собственный модуль для HomeComponent и использовать loadChildren в маршруте (app.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. Вы все равно можете установить атрибут data для любого другого маршрута, но тогда он не имеет ничего общего с ленивой загрузкой.

Вы должны прочитать это хорошо написанное 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); 
    } 
} 

Что вы также должны сделать это, чтобы экспортировать эту стратегию предварительной загрузки, чтобы использовать ее в вашем приложении.module в массиве поставщиков:

в app.routing.ц:

export const APP_ROUTES_MODULE_PROVIDER = [SelectedPreloadingStrategy]; 

и импортировать его в app.module.ts:

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

@NgModule к -providers массива:

providers: [ 
    ... 
    APP_ROUTES_MODULE_PROVIDER 
], 

Если Everthing компилирует правильно, и вы маршрут к ленивому загруженному модулю в вашем приложении, вы должны проверить Network -Tab своих инструментов разработчика и вы увидите, что маршрутизатор загрузил модуль только после того, как вы перешли к нему.

+0

У меня есть пример из этой статьи. Тем не менее, я попробовал ваше точное решение, используя другое имя для модуля и компонента ('TestComponent' и' TestModule'), но я все равно не получаю свой 'console.log'. Это то же поведение, если я использую 'component' или' loadChildren' в своих «appRoutes», отладчик разбивается на строку «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.

Смежные вопросы