2015-11-01 9 views
30

В Угловом 1 моем конфиге выглядит следующим образом:Использования Resolve В Angular2 Маршрутах

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

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

+0

AFAIK это функциональность еще не реализована. Следите за [этой проблемой] (https://github.com/angular/angular/issues/4015). На данный момент вы можете попытаться использовать ['@ CanActivate'] (https://github.com/angular/angular/blob/2.0.0-alpha.45/modules/angular2/src/router/lifecycle_annotations.ts#L20) и '@ OnActivate' (но это, конечно, не функция' resolve'). – alexpods

+0

Возможный дубликат [Angular2: получить данные родительского маршрутизатора] (http://stackoverflow.com/questions/35299238/angular2-get-parent-router-data) –

ответ

3

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

Yo ур компонент:

ngOnInit() { 
    this.route.data.subscribe((data: { message: Message }) => { 
    this.message = data.message; 
    }); 
} 
28

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

+2

только FYI, крючок - routerOnActivate (по крайней мере, в ES6/7) – iksose

+0

комментарий выше означает, что интерфейс OnActivate реализован через 'routerOnActivate', а не то, что OnActivate можно реализовать для задержки загрузки шаблона. – shannon

+3

Как вы вводите свой 'messageService'? Я пытаюсь использовать 'Injector.resolveAndCreate()'. По-видимому, он не может предоставлять зависимости приложения, указанные в 'bootstrap()', к создаваемым им службам. В результате, например, «Нет провайдера для Http» или других вещей, которые требуется моему сервису. – shannon

9

https://angular.io/docs/ts/latest/api/router/index/Resolve-interface.html «Решение» было возвращено на угловой2 маршрутизатор, но документация разрежена.

Пример:

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 
    } 
    }]) 
); 
+0

Хотя эта ссылка может ответить на вопрос, лучше включить здесь основные части ответа и предоставить ссылку для справки. Ответные ссылки могут стать недействительными, если связанная страница изменится. - [Из обзора] (/ review/low-quality-posts/12910539) –

+0

Спасибо, @RichardTelford! Все еще изучают лучшие практики здесь. Интересно, почему я использовал stackoverflow в режиме только для чтения в течение более десяти лет ... :) –

+0

Хорошо, это показывает, как сделать запрос до создания экземпляра компонента, но как/где вы получаете доступ к разрешенному значению в компоненте? –

28

На основе @ углового/маршрутизатора v3-бета, эти необходимые шаги.

Реализовать распознаватель, который возвращает наблюдаемом или простую величину:

@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. Если вы хотите, наблюдаемых сам будут доступны, то вам нужно обернуть его в другой Observable:

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

+0

Не удалось импортировать сервис 'import {HeroService} в качестве героя из './Hero.service'' в route и do 'resolve: {heroes: heroSvc.getHeroes()}'? – Baruch

+1

@Baruch вы не можете. Все, что входит в решение, используется как токен для DI. Обычно это класс, но может быть также строкой или даже но потому, что вам нужно предоставить его в первую очередь, это не сработает так, как вы намереваетесь. –

+0

спасибо за разъяснение. – Baruch

5

Вы можете создать свой Разрешитель в Angular2 + и применить его к маршрутизатору довольно легко. посмотреть на ниже, вот способ создания Разрешитель в угловых:

@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; 
    }); 
} 
Смежные вопросы