Управление состоянием NGXS: измените состояние при вызове действия и сохраните его в БД - PullRequest
0 голосов
/ 01 февраля 2019

У меня есть несколько фильмов, один из которых можно обновить, удалить и добавить в избранное с помощью шаблона управления состоянием NGXS.

Я хочу обновить свой магазин, чтобы показать, понравился ли фильм, и сохранить состояние вбаза данных.

Обновление и удаление действий работают, но подобное действие не работает, я не понимаю, почему.Это не может сохранить в БД.Если кто-то может мне помочь, я застрял.Вот мой код, спасибо.

db.json

"movies": [
{
  "id": 1,
  "title": "Avengers Infinity War",
  "imageUrl": "https://fakeimg.pl/600x600/000000/fff",
  "liked": (here I want to change the status to true or false when clicked)

},
{
  "id": 2,
  "title": "Avengers Endgame",
  "imageUrl": "https://fakeimg.pl/600x600/000000/fff"
}

]

Movie.ts

 export interface Movie {
 id: number;
 title: string;
 imageUrl: string;
 liked: boolean;
}

movie.action.ts

 export class UpdateMovie {
      static readonly type = '[Movie] UpdateMovie';
      constructor(public payload: Movie, public id: number) {}
    }

 export class DeleteMovie {
     static readonly type = '[Movie] DeleteMovie';
     constructor(public id: number) {}
    }

  export class LikeMovie {
      static readonly type = '[Movie] LikeMovie';
      constructor(public payload: Movie) {}
    }

movie-service.ts

 updateMovie(payload: Movie, id: number) {
    return this.httpClient
     .put<Movie>(encodeURI(this.URL_BASE + `movies/${id}`), payload)
   }

deleteMovie(id: number) {
  return this.httpClient
    .delete(encodeURI(this.URL_BASE + `movies/${id}`))
  }

likeMovie(payload: Movie) {
    return this.httpClient
      .post<Movie>(encodeURI(this.URL_BASE + `movies`), payload);
   }

movie.state.ts

   export class MovieStateModel {
       movies: Movie[];
       selectedMovie: Movie;
       liked: Movie[];
     }

   @State<MovieStateModel>({
      name: 'movies',
      defaults: {
      movies: [],
      selectedMovie: null,
      liked: []
    }
  })

   @Action(DeleteMovie)
   deleteMovie({ getState, setState }: StateContext<MovieStateModel>, {id}: DeleteMovie) {
    return this.movieService.deleteMovie(id).pipe(tap(() => {
      const state = getState();
      setState({
        ...state,
        movies: state.movies.filter(item => item.id !== id)
      });
    }));
   }

 @Action(UpdateMovie)
 updateMovie({ getState, setState }: StateContext<MovieStateModel> {payload, id }: UpdateMovie) {
    return this.movieService.updateMovie(payload, id).pipe(tap((result) =>
  {
      const state = getState();
      const movieList = [...state.movies];
      const movieIndex = movieList.findIndex(item => item.id === id);
      movieList[movieIndex] = result;
      setState({
         ...state,
         movies: movieList
       });
     }));
    }

 @Action(LikeMovie)
 LikeMovie({ getState, setState }: StateContext<MovieStateModel>, {payload}: LikeMovie) {
    return this.movieService.likeMovie(payload).pipe(tap(() => {
      const state = getState();
      setState({
         ...state,
         liked: [...state.liked, payload]
      });
    }));
  }

movie-list.component.ts

  likeMovie(payload: Movie) {
  this.store.dispatch(new LikeMovie(payload));
}

Ответы [ 2 ]

0 голосов
/ 02 февраля 2019

Хорошо, я провел несколько тестов и удалил запрос к БД, чтобы упростить его.

Исходя из моей модели фильма, я хочу обновить свойство liked фильма доtrue или false, когда я вызываю Like action, но вместо этого создается новое состояние с именем liked с фильмом в нем ... Я знаю, что делаю что-то не так, не могу найти правильный ответ в официальномДок и я новичок в NGXS.

Ниже приведены мои файлы:

Movie.ts

export interface Movie {
  id: number;
  title: string;
  imageUrl: string;
  liked: boolean;
}

movie.states.ts

export class MovieStateModel {
  movies: Movie[];
  selectedMovie: Movie;
}

@State<MovieStateModel>({
  name: 'movies',
  defaults: {
    movies: [],
    selectedMovie: null
  }
})

@Action(LikeMovie)
  LikeMovie({ getState, setState }: StateContext<MovieStateModel>, { payload }: LikeMovie) {
    const state = getState();
    setState({
      ...state,
      liked: payload
    });
  }

movie.actions.ts

export class LikeMovie {
  static readonly type = '[Movie] LikeMovie';

  constructor(public payload: Movie) {}
}

movie-list.component.ts

likeMovie(payload: Movie) {
    this.store.dispatch(new LikeMovie(payload));
  }
0 голосов
/ 02 февраля 2019

Добро пожаловать в StackOverflow:)

Помимо ошибки сервера (о которой Кристиан уже упоминал в комментариях), кажется, что есть небольшая ошибка в обработке действия LikeMovie.

ЕслиВаше свойство liked равно boolean, поэтому вы должны убедиться, что ему присвоено логическое значение.

setState({
  ...state,
  liked: [...state.liked, payload] <-- assigns an array
});

Правильный путь:

setState({
  ...state,
  liked: payload
});
...