Как привязать модель к formbuilder, используя реактивные формы в angular8 - PullRequest
1 голос
/ 07 мая 2020

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

HTML:

<div class="tab-pane fade h-100 active show" id="tab-user_1" role="tabpanel" aria-labelledby="user_1"
    *ngIf="userInfoForm" [formGroup]="userInfoForm">
    <div class="row">
      <div class="col-6">
        <div class="form-group">
          <label for="">Agent Code <span class="text-danger">*</span></label>
          <input type="text" formControlName="agentCode" class="form-control">
        </div>
      </div>
</div>

TS:

 this.userInfoForm = this.FB.group({
        Id: 0,
        agentCode: this.agentCode,
        userName: [''],
        firstName: [''],
        middleName: '',
        lastName: [''],
        department: [''],
      });
      this.userInfoForm.controls['agentCode'].disable();

model.ts :

export class UserFormDetails {
   Id: number;
   agentCode: number;
   userName: string;
   firstName: string;
   middleName: string;
   lastName: string;
   department: string;
}

ДЕМО

Ответы [ 3 ]

1 голос
/ 17 мая 2020

судя по комментариям, похоже, что вам нужна форма Dynami c на основе модели ... для этого нет готового решения. Вы можете написать свою собственную модель формы:

interface MyFormModelField {
  initial?: {
    value: any,
    disabled: boolean
  },
  controlOptions?: AbstractControlOptions
  // anything you find useful really?
}

export type MyFormModel<T> = Record<keyof T, MyFormModelField>

, а затем реализовать ее так:

const USER_FORM_MODEL: MyFormModel<UserFormDetails> = {
    Id: { },
    agentCode: {
        initial: {
          value: '',
          disabled: true
        },
        controlOptions: {
          validators: Validators.required
        }
    },
    userName: { },
    firstName: { },
    middleName: { },
    lastName: { },
    department: { },
}

тогда вы можете написать службу для создания групп форм на основе экземпляра модели формы ...

@Injectable({providedIn: 'root'})
export class MyFormBuilder {
  constructor(private: fb) { }

  buildForm<T>(formModel: MyFormModel<T>) {
    const fg = Object.keys(formModel).reduce((grp, k) => {
      const fld = formModel[k];
      return Object.assign(grp, {
        [k]: [fld.initial || '', fld.controlOptions]
      })
    }, {});
    return this.fb.group(fg);
  }
}

сейчас, каждый раз, когда вы вносите изменения в интерфейс UserFormDetails, машинописный текст будет кричать на вас, чтобы вы обновили соответствующую модель формы с помощью информации поля ... и пока обновления не будут поступать "автоматически" из обновления модели, у вас, по крайней мере, есть некоторая безопасность типов в ваших формах. Я бы лично остановился на этом.

Следующая часть не идеальна, и я не фанат ее, но если вы действительно хотите, чтобы следующий шаг был более или менее автоматическим, c из определения класса вы можете написать функцию для создания модели формы по умолчанию из класса, например:

function buildDefaultFormModel<T>(model: new () => T) {
  return Object.keys(new model()).reduce((form, k) => {
      return Object.assign(form, {[k]: {}})
  }, {} as MyFormModel<T>)
}

для этого требуются 2 вещи, 1, класс, для которого вы создаете форму, ДОЛЖЕН иметь значение по умолчанию указанные для каждого поля, поля без значений по умолчанию не включаются. (Это вводит скрытую зависимость от полей, имеющих значения по умолчанию, поэтому мне не нравится этот метод, однако вы МОЖЕТЕ настроить ts, чтобы он кричал на вас, если вы пишете класс, который имеет свойства без значений по умолчанию или назначений конструкторов):

class UserFormDetails {
   Id: number = 0;
   agentCode: number = 0;
   userName: string = '';
   firstName: string = '';
   middleName: string = '';
   lastName: string = '';
   department: string = '';
}

2, конструктор объекта не должен иметь параметров. но TS будет кричать на вас, если вы попытаетесь использовать его не по назначению.

функцию можно использовать так:

const USER_FORM_MODEL: MyFormModel<UserFormDetails> = {
  ...buildDefaultFormModel(UserFormDetails),
  ...{
    agentCode: {
      initial: {
        value: '',
        disabled: true
      },
      controlOptions: {
        validators: Validators.required
      }
    },
  }
}

таким образом вы можете использовать поля по умолчанию, а также предоставить переопределение для определенных c полей.

наконец, вы также можете использовать эту модель формы для создания шаблона, но это более сложная задача.

вот блиц со всем этим реализованным (и Я пошел дальше и очистил код контроллера): https://stackblitz.com/edit/github-ck3u8u-qtnasc?file=src%2Fapp%2Fuser-table%2Fuser-table.validators.ts

0 голосов
/ 17 мая 2020
• 1000 он позволяет отображать объектную модель / значения для создания модели реактивной формы.


Посмотрите, как после добавления extraField формы выбирают этот элемент управления и его значение:

enter image description here

0 голосов
/ 07 мая 2020

Вы должны использовать patchValue, чтобы привязать вашу модель к элементу управления формы FormGroup.

this.userInfoForm = this.FB.group({
        Id: 0,
        agentCode: this.agentCode,
        userName: [''],
        firstName: [''],
        middleName: '',
        lastName: [''],
        department: [''],
      });

это правильно. Когда вы получаете объект UserFormDetails, вы должны передать его в форму, которую вы должны сделать:

 this.userInfoForm.patchValue({
   'Id': UserFormDetails.id 
    ...
})

и когда вам нужно было передать значение элементов управления формы объекту:

 this.UserFormDetail.id = this.userInfoForm.get('Id').value

et c ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...