Использование разрешения в Angular2 Маршруты

В Angular 1 моя конфигурация выглядит следующим образом:

$routeProvider
  .when("/news", {
    templateUrl: "newsView.html",
    controller: "newsController",
    resolve: {
        message: function(messageService){
            return messageService.getMessage();
    }
  }
})

Как использовать решение в Angular2?

Ответ 1

@Ответ 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;
  });
}

Ответ 2

Как уже упоминалось в 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 также вызывается только со следующим и предыдущим, а не с результатом обещания. Я не доволен этим решением, но это лучшее, что я мог придумать.

Ответ 3

Основываясь на @ 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'];
}

Помните, что моментальный снимок означает значение в состоянии выполнения, как в классе компонента, так и в классе resolver. Данные не могут быть обновлены из обновлений параметров с помощью этого подхода.

Plunker: http://plnkr.co/edit/jpntLjrNOgs6eSFp1j1P?p=preview Исходный материал: https://github.com/angular/angular/commit/f2f1ec0#diff-a19f4d51bb98289ab777640d9e8e5006R436

Ответ 4

https://angular.io/docs/ts/latest/api/router/index/Resolve-interface.html "Решение" было возвращено на маршрутизатор 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
    }
  }])
);

Ответ 5

Вы можете создать свой 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;
  });
}