Использование Resolve в маршрутах Angular2
В Angular 1 мой конфиг выглядит так:
$routeProvider
.when("/news", {
templateUrl: "newsView.html",
controller: "newsController",
resolve: {
message: function(messageService){
return messageService.getMessage();
}
}
})
Как использовать разрешение в Angular2?
5 ответов
@AndréWerlang ответил хорошо, но если вы хотите, чтобы разрешенные данные на странице менялись при изменении параметра маршрута, вам необходимо:
Резольвер:
@Injectable()
export class MessageResolver implements Resolve<Message> {
constructor(private messageService: MessageService, private router: Router) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Message> {
const id = +route.params['id'];
return this.messageService.getById(id);
}
}
Ваш компонент:
ngOnInit() {
this.route.data.subscribe((data: { message: Message }) => {
this.message = data.message;
});
}
Основываясь на @angular/router v3-beta, это необходимые шаги.
Реализуйте распознаватель, который возвращает наблюдаемое или простое значение:
@Injectable()
export class HeroResolver implements Resolve {
constructor(
private service: HeroService
) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Hero> {
const id = +route.params['id'];
return Observable.fromPromise(this.service.getHero(id));
}
}
Обратите внимание, что в случае, если вы вернете наблюдаемое, развернутое значение (первое) будет доступно через route.snapshot.data
, Если вы хотите, чтобы сама наблюдаемая была доступна, вам нужно обернуть ее в другую наблюдаемую:
return Observable.of(source$);
Добавьте распознаватель к вашему маршруту:
export const HeroesRoutes: RouterConfig = [
{ path: 'heroes', component: HeroListComponent, resolve: { heroes: HeroesResolver } },
{ path: 'hero/:id', component: HeroDetailComponent, resolve: { hero: HeroResolver } }
];
Наконец, укажите класс разрешения и любую зависимость для начальной загрузки или вашего основного компонента. providers
:
bootstrap(AppComponent, [
HeroesResolver, HeroService
])
Использовать разрешенные данные из экземпляра ActivatedRoute:
ngOnInit() {
this.hero = this.route.snapshot.data['hero'];
}
Помните, что снимок означает значение в состоянии выполнения, как в классе компонента, так и в классе резолвера. Данные не могут быть обновлены после обновления параметров с помощью этого подхода.
Плункер: http://plnkr.co/edit/jpntLjrNOgs6eSFp1j1P?p=preview Исходный материал: https://github.com/angular/angular/commit/f2f1ec0
Как уже упоминалось alexpods, "решимость" как таковая отсутствует. Идея заключается в том, что вы используете хуки жизненного цикла, предоставляемые маршрутизатором. Это:
- canReuse
- canDeactivate
- OnActivate
- onReuse
- onDeactivate
Тогда есть @CanActivate. Это специальный хук, потому что он вызывается до того, как будет создан экземпляр вашего компонента. Его параметры (next, previous)
к каким компонентам вы направляете и от какого компонента вы пришли (или NULL, если у вас нет истории) соответственно.
import {Component} from '@angular/core';
import {ROUTER_DIRECTIVES, CanActivate, OnActivate} from '@angular/router';
@Component({
selector: 'news',
templateUrl: 'newsView.html',
directives: [ROUTER_DIRECTIVES]
})
@CanActivate((next) => {
return messageService.getMessage()
.then((message) => {
next.params.message = message;
return true; //truthy lets route continue, false stops routing
});
})
export class Accounts implements OnActivate {
accounts:Object;
onActivate(next) {
this.message = next.params.message;
}
}
Я еще не понял, как передать результат обещания в свой onActivate, кроме как сохранить его в своем "следующем" компоненте. Это связано с тем, что onActivate также вызывается только с next и previous, а не с результатом обещания. Я не доволен этим решением, но это лучшее, что я могу придумать.
https://angular.io/docs/ts/latest/api/router/index/Resolve-interface.html"resol" был возвращен на маршрутизатор angular2, но документация редкая.
Пример:
class TeamResolver implements Resolve {
constructor(private backend: Backend) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):Observable<any> {
return this.backend.fetchTeam(this.route.params.id);
}
}
bootstrap(AppComponent, [
TeamResolver,
provideRouter([{
path: 'team/:id',
component: TeamCmp,
resolve: {
team: TeamResolver
}
}])
);
Вы можете создать свой Resolver в Angular2+ и довольно легко применить его к маршрутизатору. посмотрите ниже, вот способ создания Resolver в Angular:
@Injectable()
export class AboutResolver implements Resolve<Message> {
constructor(private aboutService: AboutService, private router: Router) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> {
const id = route.params['id'];
return this.aboutService.getById(id);
}
}
тогда в конфиге роутера:
export const Routes: RouterConfig = [
{ path: 'about', component: AboutComponent, resolve: { data: AboutResolver } }
];
и, наконец, в вашем компоненте:
ngOnInit() {
this.route.data.subscribe((data: { about: About }) => {
this.about = data.about;
});
}