如何创建一个嵌套的ngrx-forms,可以添加或删除控件到它的子组?
在这里,我想创建一个包含两个子组语言和主题的表单
export interface LanguageFormValue {
languages: { [id: string]: { language: string, min: number, max: number } };
preferredLanguage: string;
}
export interface TopicFormValue {
favoriteTopic: string;
otherTopics: {[id: string]: { [id: string]: boolean }}
};
export interface AddNewEntryFormValue {
languages: LanguageFormValue
topics: TopicsFormValue;
}
export interface AddNewEntryFormState extends RootState {
newEntry: {
languages: {
formState: FormGroupState<LanguageFormValue>;
languageOptions: string[];
};
topics: {
formState: FormGroupState<TopicsFormValue>;
topicsOptions: string[];
};
};
}添加主题的操作
export class CreateTopicControlAction implements Action {
static readonly TYPE = '[Entry Form] Add Topic Control';
readonly type = CreateTopicControlAction.TYPE;
constructor(public name: string) { }
}针对语言的操作
export class CreateLanguageControlAction implements Action {
static readonly TYPE = '[Entry Form] Add Language Control';
readonly type = CreateGroupElementAction.TYPE;
constructor(public name: string) { }
}
export class RemoveLanguageControlAction implements Action {
static readonly TYPE = '[Entry Form] Remove Language Control';
readonly type = RemoveGroupElementAction.TYPE;
constructor(public name: string) { }
}我如何为上面的形式写一个缩减程序呢?
我尝试了很多方法,但是reducer显示错误?
有没有办法组合子formGroupStates,同时保留在这些子状态中添加或删除控件的能力?
我已经尝试将'filterBy‘作为父窗体组,并尝试为子语言和主题组添加缩减程序。但那失败了。
我还尝试将每种语言和主题分别拆分为不同的reducer.ts文件。但是,我将不得不分别注册它们中的每一个storeModule.forFeature()。它是有效的,但它正在改变我的状态树结构(这不是我想要的)。因此,我尝试使用index.ts对这些独立的reducer文件的状态和reducer进行分组,并尝试将其注册为一个功能。但这也失败了,因为控件变得未定义。
我试过其他几种方法...但是,没有什么是有效的。
有没有办法组合子formGroupStates,同时保留在这些子状态中添加或删除控件的能力?
或者我们可以这样做:但仍然希望保留添加或删除子组(语言和主题)的功能
export interface FilterByState extends RootState {
filterBy: formState: FormGroupState<FilterFormValue>;
}发布于 2020-04-25 00:54:40
ngrx-forms的作者在这里。
下面的代码应该可以(使用ngrx v8+)。我也建议你用ngrx v8+风格来创建你的动作,否则你不能正确地使用现代的缩减风格。
const createTopicControl = createAction('[Entry Form] Add Topic Control', (name: string) => ({ name }));
const createLanguageControl = createAction('[Entry Form] Add Language Control', (name: string) => ({ name }));
const removeLanguageControl = createAction('[Entry Form] Remove Language Control', (name: string) => ({ name }));
const initialState: AddNewEntryFormState = {
newEntry: {
languages: {
formState: createFormGroupState<LanguageFormValue>('LANGUAGES_FORM', {
languages: {},
preferredLanguage: '',
}),
languageOptions: [],
},
topics: {
formState: createFormGroupState<TopicFormValue>('TOPICS_FORM', {
favoriteTopic: '',
otherTopics: {},
}),
topicsOptions: [],
},
}
}
export const addNewEntryFormStateReducer = createReducer(
initialState,
onNgrxForms(),
on(createTopicControl, (state, { name }) => {
// yes, nested reducers are ugly, look at options like immer.js
// to make this less messy
return {
...state,
newEntry: {
...state.newEntry,
topics: {
...state.newEntry.topics,
formState: updateGroup(state.newEntry.topics.formState, {
otherTopics: addGroupControl(name, {}),
}),
},
},
};
}),
on(createLanguageControl, (state, { name }) => {
return {
...state,
newEntry: {
...state.newEntry,
languages: {
...state.newEntry.languages,
formState: updateGroup(state.newEntry.languages.formState, {
languages: addGroupControl(name, {
language: '',
min: 0,
max: 0,
}),
}),
},
},
};
}),
on(removeLanguageControl, (state, { name }) => {
return {
...state,
newEntry: {
...state.newEntry,
languages: {
...state.newEntry.languages,
formState: updateGroup(state.newEntry.languages.formState, {
languages: removeGroupControl(name),
}),
},
},
};
}),
);我希望这能帮到你。
https://stackoverflow.com/questions/61362669
复制相似问题