Я начинаю со структуры нескольких приложений в Angular, и я обнаружил странное поведение при выборе mat из Angular Material ...
Я не могу открыть раскрывающийся список - наложение не появляется, и обычное событие нажатияотправляется вместо материала, открытого с помощью e.preventDefault.Чтобы проверить это поведение, я использую (клик) обработчик для регистрации событий.
Если работает - журнал событий (e.preventDefault не вызывается, выберите оверлей, открытый нормально). Если нет - щелкните событие, зарегистрированное - любые изменения в пользовательском интерфейсе
Итак ... Сначала я 'Я проверил, что это может быть проблема с Материалом, поэтому я переключился на NG-Zorro - рекомендуется из рамки angular.io и все тот же ...
После многих часов отладки, тестирования иПоиск Я обнаружил, что проблема с AuthGuard - все еще не знаю почему, но позвольте мне сначала описать поток аутентификации.
Целевая страница -> Войти в Google с перенаправлением в приложение -> Авторизовать действие (ngrx), отправленное наinit (в app.component) -> эффект ngrx с отслеживанием токена gapi и отправкой действия успешной аутентификации -> эффект и вызов api для пользовательских данных -> вход в систему.
Я подготовил этот auth.effect для тестирования
@Effect()
authorize$: Observable<Action> = this.actions$.pipe(
ofType(ActionTypes.Authorize),
switchMap(() => this.authService.authState.pipe(
map(user => {
return user
? new AuthorizeSuccess(user)
: new AuthorizeFailed();
}),
catchError(() => of(new AuthorizeFailed()))
))
);
@Effect()
authorizeSuccess$: Observable<any> = this.actions$.pipe(
ofType(ActionTypes.AuthorizeSuccess),
switchMap((action: { type: string; payload: any }) => this.httpClient.get(`${environment.apiServerUrl}/users/me`)
.pipe(take(1), map(response => {
const user = new User(response ? { ...action.payload, ...ConvertingService.removeEmptyObjectValues(response) } : action.payload);
return new LoginSuccess(user);
}))
),
tap(() => setTimeout(() => this.preloaderService.setInfinitely(true, false), 100)),
catchError(() => of(new LoginFailed()))
);
Так что вы можете видеть поток действий.
Auth.reducer
export interface AuthenticationState {
authorized: boolean
profile: AuthUser
user: User
}
export const initialState: AuthenticationState = {
authorized: false,
profile: null,
user: null
};
export function authenticationReducer(
state = initialState,
action: Union
): AuthenticationState {
switch (action.type) {
case ActionTypes.AuthorizeSuccess:
return {
...state,
profile: action.payload
};
case ActionTypes.LoginSuccess:
return {
...state,
user: action.payload,
authorized: true
};
...
default:
return state;
}
}
И простой селектор
export interface AppState {
auth: AuthenticationState;
router: RouterReducerState<RouterStateUrl>;
}
export const reducers: ActionReducerMap<AppState> = {
auth: authenticationReducer,
router: routerReducer
};
// SELECTORS
export const selectAuth = (state: AppState) => state.auth;
export const selectRouter = (state: AppState) => state.router;
export const authState = createSelector(selectAuth, (state) => state.profile);
export const authorized = createSelector(selectAuth, (state) => state.authorized);
export const currentUser = createSelector(selectAuth, (state) => state.user);
Наконец-то защита, которая ничего не делает, кроме ожидания загрузки пользователя
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(private store: Store<AppState>) { }
canActivate(): Observable<boolean> {
return this.checkStore().pipe(
switchMap(() => of(true)),
catchError(() => of(false))
);
}
private checkStore(): Observable<boolean> {
return this.store.pipe(
select(authorized),
filter(authenticated => authenticated),
take(1)
);
}
}
Это добавляется к маршрутизации с
{
canActivate: [AuthGuard],
loadChildren: './modules/home/home.module#HomeModule',
path: 'home',
},
Итак ... Все выглядит хорошо для меня (если у кого-то есть хорошая практика для этого кода - любой отзыв будет приятным :)).Но когда я запускаю это и обновляю страницу, селектор хочет иногда работать.Хорошо, большую часть времени.Но когда я иду на посадку, то вход в систему, то после входа я перенаправлен на страницу, кажется, работает нормальноПроблема только в том, что я напрямую вызываю этот маршрут, когда я вхожу в систему.
См. Анимацию ниже
Другой трек состоял в том, что когда я просто return true
в этой защите, или сделайте так, чтобы это было как можно больше, например, используя какой-нибудь канал задержки или что странно, когда я отображаю это в true, это работает.Но с ожидаемой проверкой это не будет.
Я буду очень благодарен за любые предложения, потому что я потратил на это 4 последних дня с рефакторингом, тестированием и отладкой: (* 1042 *
Вот репо сПример проекта: https://github.com/wojtek1150/mat-select-error
Привет, Ш