Я сделал приложение для фильтрации и сортировки игр из списка игр.Я новичок в Angular, поэтому я хочу знать, какие ошибки я допустил и как лучше делать определенные вещи.Будет полезно, если кто-нибудь объяснит мне, что я должен сделать, чтобы улучшить свой код. (Приложение должно использовать ngrx, json-сервер, а фильтрация / сортировка должна быть во внешнем интерфейсе)
В игре.service получает игры с json-сервера и помещает их в магазин
В компоненте поиска считывайте игры из магазина, фильтруйте их и помещайте в магазин как результаты
- В компоненте списка игр прочитайте результаты и отобразите их в html, отсортировав по функции в компоненте и поместив в хранилище
- При нажатии на игру поместите эту игру в магазин и перейдите к компоненту game-деталь, которая читает игру из магазина и отображает детали игры
dashboard.component.ts:
constructor(private gameService: GameService) {
this.gameService.getGames();
}
dashboard.component.html
<app-search></app-search>
<app-games-list></app-games-list>
game.service.ts
private baseUrl = 'http://localhost:3000/games';
constructor(private httpClient: HttpClient, private store: Store<AppState>) { }
getGames(){
this.httpClient.get<Game[]>(this.baseUrl).subscribe(data => {
this.store.dispatch({ type: 'GET_GAMES', payload: data })}, error=> console.error(error));
}
search.component.html
search: Search;
formSearch: FormGroup;
gameList: Game[];
results: Game[];
constructor(private store: Store<AppState>, private gameService:
GameService) {
this.store.select("game", "games").subscribe(data => this.gameList = data);
}
ngOnInit() { }
onSubmit(searchForm) {
this.formSearch = searchForm;
this.search = searchForm.value;
if (this.search.dateStart) {
const tempDateSearch = this.search.dateStart.split("/", 3);
this.search.dateStart = tempDateSearch[1] + "/" + tempDateSearch[0] +"/"
+ tempDateSearch[2];
}
if (this.search.dateEnd) {
const tempDateSearch = this.search.dateEnd.split("/", 3);
this.search.dateEnd = tempDateSearch[1] + "/" + tempDateSearch[0] + "/" +
tempDateSearch[2];
}
this.store.dispatch({ type: 'SEARCH_GAMES', payload: this.search });
this.results = this.gameList.filter(game => {
let tempDateStart: Date;
let tempDateEnd: Date;
const tempReleaseDate = new Date(game.releaseDate);
if (this.search.dateStart) {
tempDateStart = new Date(this.search.dateStart);
}
if (this.search.dateEnd) {
tempDateEnd = new Date(this.search.dateEnd);
}
return (!this.search.title || game.title.toLocaleLowerCase().includes(this.search.title.toLocaleLowerCase()))
&& (!this.search.sale || game.sale == this.search.sale)
&& (!this.search.priceStart || game.price >= this.search.priceStart)
&& (!this.search.priceEnd || game.price <= this.search.priceEnd)
&& (!this.search.dateStart || tempReleaseDate >= tempDateStart)
&& (!this.search.dateEnd || tempReleaseDate <= tempDateEnd);
})
this.store.dispatch({ type: 'SEARCH_GAMES_COMPLETE', payload: this.results });
}
onReset() {
if (this.formSearch) {
this.formSearch.reset();
}
this.store.dispatch({ type: 'RESET_GAMES' });
this.store.dispatch({ type: 'SEARCH_GAMES_RESET' });
}
games-list.component.ts
results: Game[];
selectedGame$: Observable<Game>;
sortedGames$: Observable<Game[]>;
orderByTitle: number;
orderByDate: number;
orderByPrice: number;
constructor(private store: Store<AppState>, private router: Router, private gameService: GameService) {
this.store.pipe(select('game', 'results')).subscribe(data => this.results = data);
this.sortedGames$ = this.store.pipe(select('game', 'sortedGames'))
}
ngOnInit() {
this.orderByDate = -1;
this.orderByPrice = -1;
this.orderByTitle = -1;
}
onSelect(game: Game): void {
this.store.dispatch({ type: 'SELECTED_GAME', payload: game });
this.router.navigate(["/gamedetail"]);
}
onSortTitle(): void {
this.orderByPrice = -1;
this.orderByDate = -1;
if (this.orderByTitle == -1) {
this.orderByTitle = 0;
}
else if (this.orderByTitle == 0) {
this.orderByTitle = 1;
}
else if (this.orderByTitle == 1) {
this.orderByTitle = 0;
}
this.results = [...this.results].sort((obj1, obj2) => {
if (this.orderByTitle == 0) {
if (obj1.title > obj2.title) {
return 1;
}
if (obj1.title < obj2.title) {
return -1;
}
return 0;
}
else if (this.orderByTitle == 1) {
if (obj1.title > obj2.title) {
return -1;
}
if (obj1.title < obj2.title) {
return 1;
}
return 0;
}
})
this.store.dispatch({ type: "SORT_GAMES", payload: this.results });
}
onSortDate()...
onSortPrice()...
games-list.component.html отображение sortedGames $ с использованием асинхронного канала
game.actions.ts
(...)
export class GetGames implements Action {
readonly type = GET_GAMES
constructor(public payload: Game[]) {}
}
export class ResetGames implements Action {
readonly type = RESET_GAMES
}
export class SearchGames implements Action {
readonly type = SEARCH_GAMES
constructor(public payload: Search) {}
}
export class SearchGamesComplete implements Action {
readonly type = SEARCH_GAMES_COMPLETE
constructor(public payload: Game[]) {}
}
export class SearchGamesReset implements Action {
readonly type = SEARCH_GAMES_RESET
}
export class SortGames implements Action {
readonly type = SORT_GAMES
constructor(public payload: Game[]) {}
}
export class SelectedGame implements Action {
readonly type = SELECTED_GAME
constructor(public payload: Game) {}
}
(...)
game.reducers.ts
const initialState: AppState = {
games: [],
search: {
title: '',
dateStart: "",
dateEnd: "",
sale: false,
priceStart: null,
priceEnd: null,
},
results: [],
selectedGame: null,
sortedGames: []
}
export function gameReducer(state = initialState, action: GameActions.Actions) {
switch (action.type) {
case GameActions.GET_GAMES:
return {
...state, games: action.payload,
results: action.payload,
sortedGames: action.payload
}
case GameActions.RESET_GAMES:
return {
...state, results: state.games,
sortedGames: state.games
}
case GameActions.SEARCH_GAMES:
return {
...state, search: action.payload
}
case GameActions.SEARCH_GAMES_COMPLETE:
return {
...state, results: action.payload,
sortedGames: action.payload
}
case GameActions.SEARCH_GAMES_RESET:
return { ...state, search: initialState.search}
case GameActions.SORT_GAMES:
return { ...state, sortedGames: action.payload }
case GameActions.SELECTED_GAME:
return { ...state, selectedGame: action.payload }
default:
return state;
}
}