В случае, если кто-то еще проходит через это, моё решение следующее, и у меня есть вопрос в конце моего решения.
Следующее - мой файл 'redurs / index.ts':
import { ActionReducerMap } from "@ngrx/store";
import { reducer, User } from "./user.reducer";
interface AppState {
appReducer: User;
}
export const reducers: ActionReducerMap<AppState> = {
appReducer: reducer
};
Который также импортирует мой файл 'redurs / user.reducer.ts':
import * as UserActions from "../actions/user.actions";
/* use mTstamp function to calculate timestamp within typescript */
function mTstamp() {
let d = new Date();
let mMonth;
if (d.getMonth() < 10) {
mMonth = "0" + d.getMonth();
} else {
mMonth = d.getMonth();
}
let mDate;
if (d.getDate() < 10) {
mDate = "0" + d.getDate();
} else {
mDate = d.getDate();
}
let mHours;
if (d.getHours() < 10) {
mHours = "0" + d.getHours();
} else {
mHours = d.getHours();
}
let mMins;
if (d.getMinutes() < 10) {
mMins = "0" + d.getMinutes();
} else {
mMins = d.getMinutes();
}
let mSecs;
if (d.getSeconds() < 10) {
mSecs = "0" + d.getSeconds();
} else {
mSecs = d.getSeconds();
}
let mTimeStamp =
d.getFullYear() +
"-" +
mMonth +
"-" +
mDate +
" " +
mHours +
":" +
mMins +
":" +
mSecs;
console.log("mTimeStamp: ", mTimeStamp);
return mTimeStamp;
}
export interface User {
uName: string;
isAdmin: boolean;
ts: string;
loggedIn: boolean;
}
const initialState: User = {
uName: "Guest",
isAdmin: false,
ts: mTstamp(),
loggedIn: false
};
export function reducer(appUserState = initialState, action): User {
switch (action.type) {
case UserActions.ACTION_LOGOUT:
return {
...appUserState,
uName: "Guest",
isAdmin: false,
ts: mTstamp(),
loggedIn: false
};
case UserActions.ACTION_LOGIN:
return {
...appUserState,
uName: action.payload,
isAdmin: action.payload,
ts: action.payload,
loggedIn: action.payload
};
}
return appUserState;
}
Файл index.ts также импортирует файл 'actions / user.actions.ts':
export const ACTION_LOGIN = "LoggedIn";
export const ACTION_LOGOUT = "LoggedOut";
Это все, что мне нужно для создания редукса для входа и выхода.
В компонентах большая часть моей логики проходила через файл служб, который обрабатывает вход черезthe db:
import { Injectable } from "@angular/core";
import { Router } from "@angular/router";
import { HttpClient } from "@angular/common/http";
import { Component } from "@angular/core";
import { Store } from "@ngrx/store";
import { User } from "./reducers/user.reducer";
import { Observable } from "rxjs";
import * as UserActions from "./actions/user.actions";
@Injectable({
providedIn: "root"
})
export class ShoppingCartValuesService {
public shoppingCartValues = "n";
public loginObj: any;
public uri = "<path to some local php api>";
user: Observable<User[]>;
constructor(
private http: HttpClient,
private router: Router,
private store: Store<any>
) {}
getLogin(email, password) {
return new Observable(observe => {
this.http
.get(this.uri + "?name=" + email + "&pass1=" + password)
.subscribe(res => {
this.loginObj = res;
if (this.loginObj.uName != null || this.loginObj.uName !== "Guest") {
this.loginObj.loggedIn = true;
this.getState();
this.updateState({
action: UserActions.ACTION_LOGIN,
payload: this.loginObj
});
}
observe.next(res);
this.router.navigate(["/"]);
});
});
}
getState() {
return this.store.select("appReducer");
}
updateState(obj) {
this.store.dispatch({
type: obj.action,
payload: obj.payload
});
console.log("this.loginObj from updateState: ", this.loginObj);
}
logout() {
const logoutObj = {
action: UserActions.ACTION_LOGOUT,
payload: {
uName: "Guest",
isAdmin: 0,
ts: "2018-12-28 00:00:00",
loggedIn: false
}
};
this.store.dispatch({
type: logoutObj.action,
payload: logoutObj.payload
});
this.router.navigate(["/login"]);
}
}
Как видите, когда возвращается результат (res), я проверяю, есть ли имя пользователя в объекте JSON, что означает, что php нашел совпадение.Оттуда getState (), которая выбирает хранилище «appReducer», а updateState () отправляет изменения в хранилище.
Ниже приведена соответствующая часть панели навигации, к которой я пытался выполнить, и этоприводит к вопросу, который у меня есть, но я поставлю его в конце:
<li *ngIf="!appUserState.loggedIn" class="nav-item">
<a
class="nav-link"
data-toggle="tooltip"
title="Register"
id="register"
routerLink="/register"
><span>Register</span></a
>
</li>
<li *ngIf="!appUserState.loggedIn" class="nav-item">
<a
class="nav-link"
data-toggle="tooltip"
title="Login"
routerLink="/login"
id="login-btn"
><span>Login</span></a
>
</li>
<li *ngIf="appUserState.loggedIn" ngbDropdown class="nav-item dropdown">
<a
ngbDropdownToggle
class="nav-link dropdown-toggle"
href="//:javascript"
id="dropdown01"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
>More</a
>
<div ngbDropdownMenu class="dropdown-menu" aria-labelledby="dropdown01">
<a
class="dropdown-item"
data-toggle="tooltip"
title="My orders"
routerLink="/my-orders"
id="search-records"
><span>Search Records</span></a
>
<a
*ngIf="appUserState.isAdmin.isAdmin != '0'"
class="dropdown-item"
data-toggle="tooltip"
title="Admin search records"
routerLink="/admin/orders"
id="admin-search-records"
><span>Admin Search Records</span></a
>
<a
*ngIf="appUserState.isAdmin.isAdmin != '0'"
class="dropdown-item"
data-toggle="tooltip"
title="Admin products"
routerLink="/admin/products"
id="admin-products"
><span>Admin Products</span></a
>
Ниже приведена соответствующая часть файла app.module.ts:
import { StoreModule } from "@ngrx/store";
import { reducers } from "./reducers/";
Позже в массиве import:
StoreModule.forRoot(reducers, {}),
Теперь это работает на 100% вместе с нулевыми ошибками или предупреждениями.Однако, как вы, наверное, заметили, мне пришлось применить несколько взломать в панели навигации - * ngIf = "appUserState.isAdmin.isAdmin! = '0'"
Почему система увидит appUserState какобъект внутри объекта?Другими словами, почему он не распознал * ngIf = "appUserState.isAdmin! = '0'" - только когда я увидел, что appUserState.isAdmin был тем, чем я думал appUserState, я понял, что это позволит оценитьправда, потому что объект существовал.Когда я использовал консоль, чтобы открыть объект, и обнаружил внутри него объект, который имел свойство isAdmin, тогда я решил проблему, добавив еще один .isAdmin
Если кто-то может мне это объяснить,тогда это будет вишня поверх глазури.В противном случае, он работает, и этого пока достаточно.
Заранее спасибо