Правильный способ инициализировать поля ввода для реактивных форм и иметь действительный элемент управления - PullRequest
0 голосов
/ 18 сентября 2018

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

Допустим, у меня есть этот код:

@Component({
  selector: 'app-profile-editor',
  templateUrl: './profile-editor.component.html',
  styleUrls: ['./profile-editor.component.css']
})
export class ProfileEditorComponent {
  profileForm = this.fb.group({
    firstName: string,
    lastName: string,

    address: this.fb.group({
      fName: ['initial value', [Validators.required]],
      city: ['', [Validators.required]],
      state: [''],
      zip: ['']
    }),
  });

  constructor(private fb: FormBuilder) { }
}

И в шаблоне, который я имею, скажем:

 <input [(ngModel)]="firstName" formControlName="fName" />

Проблема в том, что установка значения по умолчанию таким способом не работает:

fName: ['initial value', [Validators.required]],

секундаспособ не работает:

fName: new FormControl('initial value', [Validators.required])

третий способ - , в шаблоне это не работает:

 <div>
    <input [(ngModel)]="firstName" formControlName="fName" [value]="'default value'"/>
 </div>

Четвертыйспособ сделать это:

this.address.controls['fName'].setvalue('default value');
this.address.controls['fName'].updateValueAndValidity();

Поэтому, когда я пробую все эти комбинации или одну из них одновременно, и захожу в отладчик и проверяю, каково значение: this.address.control ['fName']. value это дает мне пустое значение -> ''

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

может кто-нибудь объяснить, почему этоэто поведение или объяснить, как правильно поступить с этим?

Примечание: я просто привожу здесь небольшой пример кода в качестве подсказки, потому что мой реальный код является частью большего и проприетарного углового кода 6application.

Я должен очистить этот пример, но вот один, использующий:

https://stackblitz.com/edit/angular-reactive-forms-jhg6ds?file=app%2Fapp.component.ts

(обновлю этот пример позже.)

В этом случае значение по умолчанию не отображается, потому что я думаю, что это своего рода параллелизм с содержимым ngModel, поэтому я хочу установить событие этого значения по умолчанию, если содержимое ngModel пусто (например, при созданиипустая форма, пользователь должен найти поле, уже заполненное (и затем действительное))

1 Ответ

0 голосов
/ 18 сентября 2018

Отредактированная версия: https://stackblitz.com/edit/angular-reactive-forms-atvaym

шаблон:

<form [formGroup]="SignupForm" (ngSubmit)="onSubmit()">
    <div class="form-group">
        <label for="username">UserName</label>
        <input type="text" class="form-control" id="username" formControlName="username">
        <span class="help-block" *ngIf="!SignupForm.controls.username.valid && SignupForm['controls'].username.touched">
   <span *ngIf="SignupForm['controls'].username.hasError('nameIsForbidden')">name is invalid</span>
        <span *ngIf="SignupForm['controls'].username.hasError('required')">field is required</span>
        </span>
    </div>

    <div class="form-group">
        <label for="email">Email</label>
        <input type="email" class="form-control" id="email" formControlName="email">
        <span class="help-block" *ngIf="!SignupForm.controls.email.valid && SignupForm['controls'].email.touched">
   <span *ngIf="SignupForm['controls'].email.hasError('emailIsForbidden')">name is invalid</span>
        <span *ngIf="SignupForm['controls'].email.hasError('required')">field is required</span>
        </span>
    </div>

    <div class="radio" *ngFor="let gender of genders">
        <label>
<input type="radio" [value]="gender" formControlName = "gender">{{gender}}
</label>
    </div>

    <div formArrayName="hobbies">
        <h4>Hobbies</h4>
        <button class="btn btn-default" type="button" (click)="onAddHobby()">Add Hobby</button>
        <div class="form-group" *ngFor="let hobbyControl of SignupForm['controls'].hobbies['controls']; let i=index">
            <div [formGroupName]="i">
                <div [formGroup]="SignupForm['controls'].hobbies['controls'][i]">
                    <input type="text" class="form-control" formControlName="name">
                </div>
            </div>
        </div>
    </div>
    <span class="help-block" *ngIf="!SignupForm.valid && SignupForm.touched">please enter valid data</span>
    <button class="btn btn-primary" type="submit">Submit</button>
</form>

Машинопись:

  ngOnInit(){
    this.SignupForm = this.fb.group({
      username: [{value: 'default name', disabled: false}, [Validators.required, this.validateName()]],
      email: [{value: 'default name', disabled: false}, [Validators.required, Validators.email, this.validateEmail()]],
      gender: [{value: 'female', disabled: false}, [Validators.required]],
      hobbies: this.fb.array([])
    });
  }

  onAddHobby(){
    const controls = <FormArray>this.SignupForm.controls['hobbies'];
    let control = this.fb.group({
      name: [{value: 'hobbi', disabled: false}]
    });

    controls.push(control);
  }

  private validateName(): ValidatorFn {
    return (control: AbstractControl): {[key: string]: any} => {
      for(let i of this.forbiddenUserNames){
        if(i === control.value){
          return {'nameIsForbidden': true};
        } else {
          return null;
        }
      }
    }
  }

  private validateEmail(): ValidatorFn {
    return (control: AbstractControl): {[key: string]: any} => {
      if(control.value === 'test@test.com'){
        return {'emailIsForbidden': true};
      } else {
        return null;
      }
    }
  }

ирекомендуем посмотреть статью про асинхронные валидаторы https://alligator.io/angular/async-validators/

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