Нормализовать объект javascript на вложенный объект из плоского объекта при использовании angular formcontrolls

проблема связана с использованием элементов управления угловой формы, рефакторингом из ngModel

this.form.addControl('Contact.Attributes.firstname', new FormControl('', Validators.required));

NgModel подвергся рефакторингу

[(ngModel)]="object.Contact.Attributes.firstname">

Итак, у меня есть "плоский" объект, который мне нужно превратить в нормализованный объект вложенных значений ... есть ли умный способ сделать это без написания собственного парсера?

превратите это в (this.form.value)

{
 Contact.Attributes.firstname: "", 
 Contact.Attributes.middlename: "", 
 Contact.Attributes.lastname: ""
}

В это

Contact: {
  Attributes: {
    firstname: "",
    middlename: "",
    lastname: "",
}

Почему вы используете addControl, это какая-то динамическая форма? Обычно вы создаете свою форму в методе ngOnInit, например здесь

Arek Kostrzeba 14.09.2018 15:40
0
1
155
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Не могли бы вы попробовать,

const unflatten = require('flat').unflatten;

unflatten({
    'three.levels.deep': 42,
    'three.levels': {
        nested: true
    }
})

Результат:

// {
//     three: {
//         levels: {
//             deep: 42,
//             nested: true
//         }
//     }
// }

https://github.com/hughsk/flat

это то, что я искал плохо, попробуй скорее

Ricardo Saracino 14.09.2018 01:19

Хотя это отлично отвечает на вопрос, я в итоге выбрал решение Arek Kostrzeba, это останется принятым ответом

Ricardo Saracino 14.09.2018 15:54

Для реактивных форм

/**
 * Add a control to this group.
 *
 * This method also updates the value and validity of the control.
 *
 * @param name The control name to add to the collection
 * @param control Provides the control for the given name
 */
addControl(name: string, control: AbstractControl): void;

Это означает, что вы можете передать объект FormControl или FormGroup методу addControl, потому что оба эти объекта являются экземплярами AbstractControl. Более того, даже ваш this.form является экземпляром FormGroup

/** Component */
this.form.addControl('Contact', new FormGroup({
    Attributes: new FormGroup({
      firstName: new FormControl('', Validators.required),
      lastName: new FormControl('', Validators.required)
    })
}));

/** Template bindings */
<form [formGroup]="form">
   <div [formGroup]="form.controls.Contact.controls.Attributes">
    <input formControlName="firstName" id="firstName" type="text" class="form-control" />
    <input formControlName="lastName" id="lastName" type="text" class="form-control" />
  </div>
</form>

Для форм на основе шаблонов

оберните свой ввод директивой ngModelGroup

<div ngModelGroup="Contact" >
  <div ngModelGroup="Attributes" >
    <input [(ngModel)]="object.firstname" name="firstname" id="firstname" class="form-control"/>
  </div>
</div>

тогда ваши данные будут поступать в ваш компонент в той форме, в которой вы хотите.

Здесь вы можете поиграть с живым примером. create-event.component имеет расположение ngModelGroup.

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

Ricardo Saracino 14.09.2018 15:20

Вот как они это оформляют. Решение с unflatten выглядит немного хакерским в контексте Angular, но его достаточно для простых форм. На мой взгляд, для сложных или динамических форм лучше следовать правилам Angular.

Arek Kostrzeba 14.09.2018 15:33

вы знаете, что вы, вероятно, правы, я на самом деле пробую этот способ прямо для сравнения. Я обнаружил, что form.get ('name.with.dots') возвращает null

Ricardo Saracino 14.09.2018 15:37

Для доступа к дочерним элементам используйте свойство form.controls.Contact.controls.Attributes. Конечно, вам нужно создать свою форму Angular, чтобы сделать это

Arek Kostrzeba 14.09.2018 15:43

хм, это работает как ожидалось [formControl]="form.controls.Contact.controls.Attributes.get‌​('firstname'), кажется ужасно многословным. но я могу по крайней мере проверить всю форму и добавлять и удалять правила по мере необходимости

Ricardo Saracino 14.09.2018 15:45

возможно, придется пойти по этому пути, чтобы получить преимущества динамического добавления удаления полей формы *ngIf="form.controls.Contact.controls.Attributes.get('firstn‌​ame')"

Ricardo Saracino 14.09.2018 15:47

поэтому я изменил его на [formControl]="form.get('Contact').get('Attributes').get('fi‌​rstname')", чтобы IDE была довольна и стала на несколько символов меньше

Ricardo Saracino 14.09.2018 15:52

Вы можете объявить свои элементы управления как общедоступные свойства в своем компоненте, а затем использовать эти свойства непосредственно в шаблоне. Это своего рода стенография. Я отредактирую свой ответ позже.

Arek Kostrzeba 14.09.2018 15:53

похоже на компромисс, у меня будет куча детей, поэтому количество свойств против убеждения - это компромисс. честно говоря, это отлично работает

Ricardo Saracino 14.09.2018 15:57

Другие вопросы по теме