NGXS 状态管理:调用动作时更改状态并将其保存到数据库
NGXS state management : change the state when an action is called and save it to DB
我有几部电影,可以通过 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) {}
}
电影-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]
});
}));
}
电影-list.component.ts
likeMovie(payload: Movie) {
this.store.dispatch(new LikeMovie(payload));
}
欢迎使用 Whosebug :)
除了服务器错误(Christian 已经在评论中提到)之外,在处理 LikeMovie
操作时似乎还有一个小错误。
如果您的 liked
属性 是 boolean
那么您应该确保为其分配了一个布尔值。
setState({
...state,
liked: [...state.liked, payload] <-- assigns an array
});
正确的方法是:
setState({
...state,
liked: payload
});
好的,所以我做了一些测试,我已经删除了对数据库的请求以使其简单。
根据我的电影模型,我想在调用 Like action
时将电影的 liked
属性 更新为 true 或 false,但它创建了一个新状态叫 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) {}
}
电影-list.component.ts
likeMovie(payload: Movie) {
this.store.dispatch(new LikeMovie(payload));
}
我有几部电影,可以通过 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) {}
}
电影-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]
});
}));
}
电影-list.component.ts
likeMovie(payload: Movie) {
this.store.dispatch(new LikeMovie(payload));
}
欢迎使用 Whosebug :)
除了服务器错误(Christian 已经在评论中提到)之外,在处理 LikeMovie
操作时似乎还有一个小错误。
如果您的 liked
属性 是 boolean
那么您应该确保为其分配了一个布尔值。
setState({
...state,
liked: [...state.liked, payload] <-- assigns an array
});
正确的方法是:
setState({
...state,
liked: payload
});
好的,所以我做了一些测试,我已经删除了对数据库的请求以使其简单。
根据我的电影模型,我想在调用 Like action
时将电影的 liked
属性 更新为 true 或 false,但它创建了一个新状态叫 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) {}
}
电影-list.component.ts
likeMovie(payload: Movie) {
this.store.dispatch(new LikeMovie(payload));
}