После того, как я внедрил хранилища NGRX в своем приложении, я обнаружил, что мой HomeComponent загружается слишком много раз.
Поток, как показано ниже, с самого начала:
1 - При вызове страницы пытается загрузить панель мониторинга, но AuthGuard сообщает, что пользователь не вошел в систему, и загружает компонент LoginComponent.
приложение-routing.module.ts
const routes: Routes = [
{
path: 'login',
loadChildren: './landing/landing.module#LandingModule'
},
{
path: '',
canActivate: [AuthGuard],
loadChildren: './dashboard/dashboard.module#DashboardModule'
}
];
2 - Затем пользователь выбирает для входа через Facebook.
login.component.ts
signInWithFacebook() {
this.store.dispatch(new FacebookLogIn());
}
3 - редуктор вызывается, вызовите мой LoginService и, если аутентификация в порядке, отправьте эффект LogInSuccess. Чтобы возобновить, я не буду размещать эту часть.
4 - Если вход в систему выполнен успешно, мне нужно загрузить другую информацию о пользователе, поэтому я звоню в другие магазины и только затем перехожу к моему DashboardComponent.
@Effect({ dispatch: false })
LogInSuccess: Observable<any> = this.actions.pipe(
ofType(LoginActionTypes.LOGIN_SUCCESS),
tap(action => {
this.zone.run(() => {
this.store.dispatch(new GetData(action.payload.user.email));
this.store.dispatch(new GetData2(action.payload.user.uid));
localStorage.setItem('user', JSON.stringify(action.payload.user));
this.router.navigate(['/dashboard'])
});
})
);
5 - Панель инструментов загружает HomeComponent вместе.
приборная панель-routing.module.ts
{
path: 'dashboard',
component: DashboardComponent,
canActivate: [AuthGuard],
children: [
{
path: '',
component: HomeComponent,
},
...
...
]
}
6 - звонки магазина приводят к следующему:
7 - И здесь проблема. Если я создаю файл console.log в HomeComponent, я вижу, что он вызывается 1 раз для каждого магазина, как показано ниже.
Вопросы:
Почему?
Что я должен сделать, чтобы предотвратить все эти ненужные нагрузки?
Если я удаляю одну из вышеприведенных рассылок, она отправляется HomeComponent только 3 раза, а не 5, как на рисунке, потому что она удаляет 2 эффекта.
- Обновление -
HomeComponent.ts
isTermSigned = false;
homeInfo = {
isBeta: false,
isTermSigned: false,
displayName: '',
email: ''
};
homeSubscription: Subscription;
constructor(
private afs: AngularFirestore,
private router: Router,
private store: Store<AppState>
) { }
ngOnInit() {
this.homeSubscription = combineLatest(
this.store.pipe(select(selectData)),
this.store.pipe(select(selectStatusLogin))
).subscribe(([data, login]) => {
console.log(login);
if (login.user) {
this.homeInfo = {
isBeta: data.isBeta,
isTermSigned: data.isBeta,
displayName: login.user.displayName,
email: login.user.email
};
}
});
}
- Обновление 2 -
Вот важная часть хранилища данных
data.action.ts
export class GetData implements Action {
readonly type = PlayerActionTypes.GET_BETA_USER;
constructor(public payload: any) {}
}
export class GetDataSuccess implements Action {
readonly type = PlayerActionTypes.GET_DATA_SUCCESS;
constructor(public payload: any) {}
}
data.effect.ts
@Effect()
GetData: Observable<any> = this.actions.pipe(
ofType(PlayerActionTypes.GET_DATA),
mergeMap(email =>
this.dataService
.getData(email)
.then(data=> {
return new GetDataSuccess({
isBeta: data.email ? true : false,
isTermSigned: data.acceptTerms ? true : false
});
})
.catch(error => {
return new GetDataError({
isBetaUser: false,
isTermSigned: false
});
})
)
);
@Effect({ dispatch: false })
GetDataSuccess: Observable<any> = this.actions.pipe(
ofType(PlayerActionTypes.GET_DATA_SUCCESS),
tap(action => {
localStorage.setItem('data', JSON.stringify(action.payload));
})
);
data.reducer.ts
export interface State {
isBeta: boolean;
isTermSigned: boolean;
}
export const initialState: State = {
isBeta: false,
isTermSigned: false
};
export function reducer(state = initialState, action: All): State {
switch (action.type) {
case DataActionTypes.GET_DATA_SUCCESS: {
return {
...state,
isBeta: action.payload.isBeta,
isTermSigned: action.payload.isTermSigned
};
}
case DataActionTypes.GET_DATA_ERROR: {
return {
...state,
isBeta: action.payload.isBeta,
isTermSigned: action.payload.isTermSigned
};
}
...
default: {
const data = JSON.parse(localStorage.getItem('data'));
if (data) {
return {
...state,
isBeta: betaUser.isBeta,
isTermSigned: betaUser.isTermSigned
};
} else {
return state;
}
}
}
}
data.selector.ts
import { AppState } from '../reducers';
export const selectData = (state: AppState) => state.data;
- Обновление 3 -
Еще одна вещь, которая может помочь и разрушает мой разум, когда я выхожу из системы, вызывается один и только один эффект, но мой HomeComponent, который вообще не имеет перенаправления, вызывается дважды:
{isAuthenticated: true, user: {…}, errorMessage: null}
{isAuthenticated: false, user: null, errorMessage: null}