Угловая 6 реактивная форма.Как построить форму для нескольких языков - PullRequest
0 голосов
/ 14 октября 2018

Я работаю над CMS с Angular 6, у меня есть форма для создания страницы на двух или более языках в зависимости от поддерживаемых локалей из настроек.Во-первых, я получаю поддерживаемые локали из api и скажем, что ответ имеет 2 локали (en - fr).Поэтому для каждого языка я хочу создать вкладку внутри формы с ее собственным языковым стандартом, например en ['title'], en ['body'], fr ['title'], fr ['body'].Я попытался построить форму следующим образом:

let forms = [];
for(let lang of this.supportedLocales) {
    forms.push(this.fb.group({
      title: ['', [Validators.required]],
      body: ['', [Validators.required]]
    }))
  }

  this.form = this.fb.group({
    template: ['default', [Validators.required]],
    is_home: [0],
    translatable: this.fb.array(forms)
  });
}

И в HTML:

<div class="tab-content">
    <div *ngFor="let lang of supportedLocales"
         class="tab-pane {{lang.locale === currentLang ? 'active' : ''}}"
         id="{{ 'tab_'+ lang.locale}}">

      <div class="form-group">
        <label [attr.for]="'title'+lang.locale">{{ translateField('page::pages.title') }}</label>
        <input formControlName="?" [attr.id]="'title'+lang.locale" class="form-control">
      </div>
    </div>
  </div>

Как определить formControlName для поля заголовка?Я пытался использовать FormArray, но это вызывает проблему, и браузер не отвечает!

Что мне делать или как лучше всего подойти для этого случая?

1 Ответ

0 голосов
/ 14 октября 2018

Я просто использую .map на this.supportedLocales, а затем сгенерирую FormGroup s, используя метод getFormGroupForLocale.Это private, поскольку он не будет использоваться в вашем шаблоне.

Теперь, когда форма будет готова, сначала я свяжу всю форму с тегом form, используя [formGroup]="form".После этого, поскольку моя форма имеет FormArray, мне сначала нужно создать для нее обтекание div.Этому div я назначу formArrayName="translatable", который сопоставит этот div с моим translatable FormArray в form FormGroup.

Внутри этого я буду использовать *ngFor="let group of localeFormArray; let i = index;"перебрать все FormGroup в моем FormArray и связать их с упаковкой div, используя <div [formGroupName]="i">.Обратите внимание, как я использую formGroupName в качестве синтаксиса привязки свойств и присваиваю ему индекс i FormGroup в моем FormArray

Наконец, внутри каждого тега input этого div,Затем я могу использовать formControlName="title" и formControlName="body" для привязки к FormControl с в каждом FormGroup с в FormArray.

Вот как:

<form [formGroup]="form">
  template
  is_home
  translatable
  <label for="template">Template</label>
  <input type="text" id="template" formControlName="template">

  <br><br>

  <label for="is_home">Is Home</label>
  <input type="text" formControlName="is_home" id="is_home">

  <br><br>

  <h1>translatable</h1>
  <div formArrayName="translatable">
    <div *ngFor="let group of localeFormArray; let i = index;">
      <div [formGroupName]="i">
        <label 
          [for]="'title'+supportedLocales[i].lang.locale">
          {{ translateField('page::pages.title') }}
        </label>
        <input 
          formControlName="title" 
          [id]="'title'+supportedLocales[i].lang.locale" 
          class="form-control">

        <br><br>

        <label 
          [for]="'title'+supportedLocales[i].lang.locale">
          {{ translateField('page::pages.title') }}
        </label>
        <input 
          formControlName="body" 
          [id]="'title'+supportedLocales[i].lang.locale" 
          class="form-control">

      </div>
    </div>
  </div>


</form>

Идля класса компонентов:

import { Component } from '@angular/core';
import { FormGroup, FormControl, FormBuilder, Validators, FormArray } from '@angular/forms';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  form: FormGroup;
  supportedLocales = [
    { lang: { locale: 'en-US' } },
    { lang: { locale: 'en-FR' } },
  ];

  constructor(private fb: FormBuilder) {}

  ngOnInit() {
    this.form = this.fb.group({
      template: ['default', [Validators.required]],
      is_home: [0],
      translatable: this.fb.array(this.supportedLocales.map(locale => this.getFormGroupForLocale(locale)))
    });
  }

  private getFormGroupForLocale(language) {
    return this.fb.group({
      title: [language.lang.locale + 'Title', [Validators.required]],
      body: [language.lang.locale+'Body', [Validators.required]]
    });
  }

  ...

  get localeFormArray() {
    return (<FormArray>this.form.get('translatable')).controls;
  }

}

Вот Образец StackBlitz для вашей ссылки.

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