如何在不将 id 从 angular 应用程序传递到 ngrx/entity 的 firestore 的情况下创建项目?
How to create item without passing id from angular app to firestore with ngrx/entity?
我正在尝试使用 Angular + Cloud Firestore + NGRX/Entity.
执行完整的 CRUD 操作
Id 是执行 ngrx/entity 所必需的参数。但是当我从我的 angular 表单创建一个项目到我的 firestore 时,我还不知道 ID,因为它会自动分配给我未来创建的文档 ID。
如何在不发送 ID 的情况下使用 ngrx/entity 将数据发送到 firestore?
我的界面如下:
实体接口:
export interface Recipe {
id: string;
recipeTitle: string;
}
actions.ts:
export const addRecipe = createAction(
'[Recipe Add Component] Add Recipe',
props<{ recipe: Recipe }>()
);
export const addRecipeSuccess = createAction(
'[Recipe Add Effect] Add Recipe Success',
props<{ recipe: Recipe }>()
);
export const addRecipeFailure = createAction(
'[Recipe Add Effect] Add Recipe Failure',
props<{ error: any }>()
);
Reducer.ts
// entity adapter
export const recipeAdapter: EntityAdapter<Recipe> = createEntityAdapter<Recipe>({
});
export interface RecipeState extends EntityState<Recipe> {
error: any;
selectedRecipe: Recipe;
}
export const initialState: RecipeState = recipeAdapter.getInitialState({
error: undefined,
selectedRecipe: undefined
});
export const recipeReducer = createReducer(
initialState,
on(RecipeActions.addRecipeSuccess, (state, action) => {
return recipeAdapter.addOne(action.recipe, state);
}),
on(RecipeActions.addRecipeFailure, (state, action) => {
return {
...state,
error: action.error
};
}),
Effects.ts
createRecipe$ = createEffect(() =>
this.actions$.pipe(
ofType(fromRecipeActions.addRecipe),
mergeMap(action =>
this.recipeService.createRecipe(action.recipe).pipe(
map(recipe => fromRecipeActions.addRecipeSuccess({recipe})),
catchError(error =>
of(fromRecipeActions.addRecipeFailure({ error }))
)
)
)
)
);
创建Component.ts
createRecipe(formGroup): void {
const recipeCreated = {
recipeTitle: formGroup.recipeTitle
};
this.store.dispatch(actions.addRecipe({recipe: recipeCreated}));
this.router.navigate(['tabs/recipe']);
}
service.ts
createRecipe(recipe): Observable<any> {
return from(this.firestore.collection(`recipes`).add(recipe));
}
getRecipes(): Observable<any[]> {
return this.firestore.collection<Recipe>('recipes').snapshotChanges().pipe(map(arr => {
return arr.map(doc => {
const data = doc.payload.doc.data();
return {
id: doc.payload.doc.id,
...data
} as Recipe;
});
}));
}
deleteRecipe(recipeId: string) {
return from(this.firestore.collection<Recipe>('recipes/').doc(recipeId).delete());
}
您可以创建一个自定义 ID 选择器,使 id 可选:
export const recipeAdapter: EntityAdapter<Recipe> = createEntityAdapter<Recipe>({
selectId: t => t.id || 0
});
我正在尝试使用 Angular + Cloud Firestore + NGRX/Entity.
执行完整的 CRUD 操作Id 是执行 ngrx/entity 所必需的参数。但是当我从我的 angular 表单创建一个项目到我的 firestore 时,我还不知道 ID,因为它会自动分配给我未来创建的文档 ID。
如何在不发送 ID 的情况下使用 ngrx/entity 将数据发送到 firestore?
我的界面如下:
实体接口:
export interface Recipe {
id: string;
recipeTitle: string;
}
actions.ts:
export const addRecipe = createAction(
'[Recipe Add Component] Add Recipe',
props<{ recipe: Recipe }>()
);
export const addRecipeSuccess = createAction(
'[Recipe Add Effect] Add Recipe Success',
props<{ recipe: Recipe }>()
);
export const addRecipeFailure = createAction(
'[Recipe Add Effect] Add Recipe Failure',
props<{ error: any }>()
);
Reducer.ts
// entity adapter
export const recipeAdapter: EntityAdapter<Recipe> = createEntityAdapter<Recipe>({
});
export interface RecipeState extends EntityState<Recipe> {
error: any;
selectedRecipe: Recipe;
}
export const initialState: RecipeState = recipeAdapter.getInitialState({
error: undefined,
selectedRecipe: undefined
});
export const recipeReducer = createReducer(
initialState,
on(RecipeActions.addRecipeSuccess, (state, action) => {
return recipeAdapter.addOne(action.recipe, state);
}),
on(RecipeActions.addRecipeFailure, (state, action) => {
return {
...state,
error: action.error
};
}),
Effects.ts
createRecipe$ = createEffect(() =>
this.actions$.pipe(
ofType(fromRecipeActions.addRecipe),
mergeMap(action =>
this.recipeService.createRecipe(action.recipe).pipe(
map(recipe => fromRecipeActions.addRecipeSuccess({recipe})),
catchError(error =>
of(fromRecipeActions.addRecipeFailure({ error }))
)
)
)
)
);
创建Component.ts
createRecipe(formGroup): void {
const recipeCreated = {
recipeTitle: formGroup.recipeTitle
};
this.store.dispatch(actions.addRecipe({recipe: recipeCreated}));
this.router.navigate(['tabs/recipe']);
}
service.ts
createRecipe(recipe): Observable<any> {
return from(this.firestore.collection(`recipes`).add(recipe));
}
getRecipes(): Observable<any[]> {
return this.firestore.collection<Recipe>('recipes').snapshotChanges().pipe(map(arr => {
return arr.map(doc => {
const data = doc.payload.doc.data();
return {
id: doc.payload.doc.id,
...data
} as Recipe;
});
}));
}
deleteRecipe(recipeId: string) {
return from(this.firestore.collection<Recipe>('recipes/').doc(recipeId).delete());
}
您可以创建一个自定义 ID 选择器,使 id 可选:
export const recipeAdapter: EntityAdapter<Recipe> = createEntityAdapter<Recipe>({
selectId: t => t.id || 0
});