路由器防护不起作用

时间:2017-07-03 21:49:04

标签: angular rxjs ngrx ngrx-store angular-router-guards

所以,我试图跟随ngrx / example-app并且我堆叠着路由器警卫。 我的警卫不起作用。

import 'rxjs/add/operator/take';
import 'rxjs/add/operator/filter';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/switchMap';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/let';
import { Injectable } from '@angular/core';
import { Store } from '@ngrx/store';
import { Router, CanActivate, ActivatedRouteSnapshot } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { Action } from '@ngrx/store';

import * as fromRoot from '../reducers';
import * as playlists from '../actions/playlists';

@Injectable()
export class PlaylistsExistsGuard implements CanActivate {
constructor(
    private store: Store<fromRoot.AppState>,
    private router: Router
) {}

waitForCollectionToLoad(): Observable<boolean> {
    return this.store.select(fromRoot.getPlaylistsLoaded)
        .filter(loaded => loaded)
        .take(1);
}

hasPlaylistsInStore(): Observable<boolean> {
    return this.store.select(fromRoot.getPlaylists)
        .map(playlists => !!playlists)
        .take(1);
}

getPlaylistsFromApi(): Observable<boolean> {
    this.store.dispatch(new playlists.GetPlaylistsAction());
    return this.store.select(fromRoot.getPlaylists)
        .map(playlists => !!playlists)
        .take(1);
}

hasPlaylists(): Observable<boolean> {
    console.log('pew pew'); // nothing happens here =(
    return this.hasPlaylistsInStore()
        .switchMap(inStore => {
            if (inStore) {
                return of(inStore);
            }

            return this.getPlaylistsFromApi();
        });
}

canActivate(route: ActivatedRouteSnapshot): Observable<boolean> {
    return this.waitForCollectionToLoad()
        .switchMap(() => this.hasPlaylists());
}
}

加载属性存在于reducer中并被选中。 сode执行没有到达hasPlaylists函数所以我认为switchMap不起作用,但我无法理解为什么=)

UPD:添加路由器声明

import {
    PlaylistsExistsGuard
} from './guards';
{
     path: 'playlists',
     component: MusicComponent,
     canActivate: [PlaylistsExistsGuard]
}
UPD:我认为我找到了解决方案。 如果我在这里使用 map 而不是过滤器

 waitForCollectionToLoad(): Observable<boolean> {
    return this.store.select(fromRoot.getPlaylistsLoaded)
        .map(loaded => loaded) //here
        .take(1);
}

并在此采取行动:

getPlaylistsFromApi(): Observable<boolean> {
    this.store.dispatch(new playlists.GetPlaylistsAction());
    return this.actions$
        .ofType(playlists.GET_PLAYLISTS_COMPLETE)
        .mapTo(true);
}

UPD:正如@Skeptor在评论中所说,我不需要map来获取元素,所以我可以在这里删除它

waitForCollectionToLoad(): Observable<boolean> {
    return this.store.select(fromRoot.getPlaylistsLoaded)
        .take(1);
}

后卫工作正常,但我仍然不明白为什么它不适用于过滤器 = /

0 个答案:

没有答案