Как создать вложенные ngrx-формы, которые могут добавлять или удалять элементы управления для своих дочерних групп? - PullRequest
1 голос
/ 22 апреля 2020

Как создать вложенные ngrx-формы, которые могут добавлять или удалять элементы управления для своих дочерних групп?

Здесь я хочу создать форму с двумя подгруппами языки и темы

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) { }
}

Как мне написать редуктор для вышеуказанной формы?

Я пробовал много способов, но редуктор показывает ошибки?

Есть ли способ объединить sub formGroupStates, сохраняя при этом возможность добавлять или удалять элементы управления в этих подсостояниях?

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

Я также попытался разделить каждый из языков и разделов по отдельности на разные файлы reducer.ts. Но тогда мне придется зарегистрировать каждый из них storeModule.forFeature () отдельно. Это работало, но это меняет мою структуру дерева состояний (а это не то, что я хочу). Поэтому я попытался сгруппировать состояния и редукторы этих отдельных файлов редукторов, используя index.ts, и попытался зарегистрировать его как функцию. Но это также не удалось, так как элементы управления стали неопределенными.

Я пробовал пару других способов ... Но отметить, работает.

Есть ли способ объединить sub formGroupStates при сохранении способности добавить или удалить элементы управления в этих подсостояниях?

или мы можем сделать это так: но все еще хотим сохранить добавление или удаление функций для дочерних групп (языки и темы)

export interface FilterByState extends RootState {
  filterBy: formState: FormGroupState<FilterFormValue>;

}

1 Ответ

1 голос
/ 24 апреля 2020

Автор ngrx-форм здесь.

Следующее должно работать (с использованием 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),
          }),
        },
      },
    };
  }),
);

Надеюсь, это поможет.

...