angular-router – Stepan Suvorov Blog https://stepansuvorov.com/blog Release 2.0 Sat, 01 Jul 2017 18:54:30 +0000 en-US hourly 1 https://wordpress.org/?v=6.3.1 Angular: Меняем title в зависимости от стейта https://stepansuvorov.com/blog/2017/03/angular-set-title/ https://stepansuvorov.com/blog/2017/03/angular-set-title/#comments Sat, 25 Mar 2017 10:23:58 +0000 http://stepansuvorov.com/blog/?p=3319 Continue reading ]]> Для того чтобы сделать динамический title в Angular (2+) нам не нужно придумывать свои велосипеды как это было в AngularJs. Достаточно просто использовать сервис Title, у которого есть методы getTitle и setTitle.

То есть если вы просто хотите задать тайтл достаточно сделать:

[javascript]
export class AppComponent implements OnInit {
constructor(private titleService: Title) {}
ngOnInit() {
this.titleService.setTitle(‘My Page Title’);
}
}
[/javascript]

При этом Title подключается из модуля @angular/platform-browser:

[javascript]
import { Title } from ‘@angular/platform-browser’;
[/javascript]

Тут вроде как все понятно, но что, если мы захотим динамически менять тайтл в зависимости от стейта/странички на которой находимся?

Todd Motto предлагает следующее решение.
Внимание! В представленном ниже примере поправлены имена некоторых переменных по сравнению с оригиналом.
Сначала мы прописывем значение title для всех стейтов в конфигурации роутера:

[javascript]
const routes: Routes = [{
path: ‘calendar’,
component: CalendarComponent,
children: [
{ path: ”, redirectTo: ‘new’, pathMatch: ‘full’ },
{ path: ‘all’, component: CalendarListComponent, data: { title: ‘My Calendar’ } },
{ path: ‘new’, component: CalendarEventComponent, data: { title: ‘New Calendar Entry’ } },
{ path: ‘:id’, component: CalendarEventComponent, data: { title: ‘Calendar Entry’ } }
]
}];
[/javascript]

а потом получаем по событию NavigationEnd:

[javascript]
export class AppComponent implements OnInit {
constructor(
private router: Router,
private activatedRoute: ActivatedRoute,
private titleService: Title
) {}
ngOnInit() {
//смотрим на все события роутера
this.router.events
//фильтруем по событию NavigationEnd
.filter(event => event instanceof NavigationEnd)
//переключаем поток на сервис activatedRoute
.map(() => this.activatedRoute)
//нас интересуют только корневые роуты (это опционально)
.map(route => {
while (route.firstChild) route = route.firstChild;
return route;
})
// так же мы выбираем только первичные аутлеты (тоже опционально)
.filter(route => route.outlet === ‘primary’)
// выбираем title
.mergeMap(route => route.data.title)
//задаем
.subscribe(stateTitle => this.titleService.setTitle(stateTitle);
}
[/javascript]

]]>
https://stepansuvorov.com/blog/2017/03/angular-set-title/feed/ 1
Angular: Lazy Loading and Preloading strategy https://stepansuvorov.com/blog/2017/03/angular-lazy-loading-and-preloading-strategy/ https://stepansuvorov.com/blog/2017/03/angular-lazy-loading-and-preloading-strategy/#comments Sun, 05 Mar 2017 10:53:59 +0000 http://stepansuvorov.com/blog/?p=3286 Continue reading ]]> Almost all of you know that it’s possible in Angular to load modules asynchronously by using Lazy Loading Router feature, you just need to specify special parameter for the state – loadChildren:

[javascript]
{ path: ‘lazy’, loadChildren: ‘./lazy/lazy.module#LazyModule’ }
[/javascript]

and setup child module with RouterModule.forChild method:

[javascript]
const routes: Routes = [
{ path: ”, component: AdminComponent }
];

@NgModule({
imports: [
CommonModule,
RouterModule.forChild(routes)
],
declarations: [AdminComponent]
})
export class LazyModule { }
[/javascript]

In most cases you are doing so not to load all the modules at once make “first screen” appearing quicker. But it’s not all folks, you also could preload all your lazy modules when your application base is loaded so: you are showing first screen fast and after load other modules in background to show them immediately when it’s needed. And it’s really usy to setup: for you main RouterModule you add the property preloadingStrategy:

[javascript]
imports: [
CommonModule,
RouterModule.forRoot(appRoutes, { preloadingStrategy: PreloadAllModules }),

],

[/javascript]

But even more interesting that you could create your own strategy for loading logic. For example you want to start loading the rest of the modules in 5s after app is loaded:

[javascript]
export class CustomPreloadingStrategy implements PreloadingStrategy {
preload(route: Route, fn: () => Observable<boolean>): Observable<boolean> {
return Observable.of(true).delay(5000).flatMap( (_: boolean)=> fn());
}
}
[/javascript]

and you can also specify which routes should not be preloaded:

[javascript]
export class CustomPreloadingStrategy implements PreloadingStrategy {

public preload(route: Route, fn: () => Observable<boolean>): Observable<boolean> {
if (route.data && route.data[‘nopreload’]) {
return Observable.of(false);
}

return Observable.of(true).delay(5000).flatMap((_: boolean) => fn());
}
}
[/javascript]

]]>
https://stepansuvorov.com/blog/2017/03/angular-lazy-loading-and-preloading-strategy/feed/ 3