禁用角度形式的输入
Posted
技术标签:
【中文标题】禁用角度形式的输入【英文标题】:Disable input on angular form 【发布时间】:2019-08-29 09:23:32 【问题描述】:嗨,我正在使用 Angular 7,我想禁用检索用户信息的输入,但是当我使用时,[disabled] = true
它不起作用我想禁用 lastname
字段,
我尝试了这个,但是当我这样做并发送表单时,它不会发送 json 上禁用的输入
这是我在代码 html 中的表单:
<div id="forms" class="page-layout simple fullwidth" fxLayout="column">
<!-- HEADER -->
<div class="header accent p-24 h-160" fxLayout="row" fxLayoutAlign="start center">
<div fxLayout="column" fxLayoutAlign="center start">
<div fxLayout="row" fxLayoutAlign="start center">
<mat-icon class="secondary-text s-18">home</mat-icon>
<mat-icon class="secondary-text s-16">chevron_right</mat-icon>
<span class="secondary-text">Contact</span>
</div>
<div class="h1 mt-16">Contact</div>
</div>
</div>
<!-- / HEADER -->
<div class="content p-24">
<p class="pt-16 pb-32">
'contact.Veuillez remplir le formulaire ci-dessous pour effectuer votre demande.Nous allons traiter votre requête dans les plus brefs délais.' | translate
</p>
<div class="mb-24" fxLayout="column" fxLayoutAlign="center center" fxLayout.gt-md="row">
<form class="mat-card mat-elevation-z4 p-24 mr-24" fxLayout="column" fxLayoutAlign="start" fxFlex="1 0 auto"
name="form" [formGroup]="form">
<div class="" style="text-align: center">
<img class="logo-ca" src="assets/images/logos/snap.png">
</div>
<div fxLayout="row" fxLayoutAlign="start center" fxFlex="1 0 auto">
<mat-form-field appearance="outline" fxFlex="50" class="pr-4">
<mat-label>'contact.First name' | translate</mat-label>
<input matInput formControlName="firstname">
<mat-icon matSuffix class="secondary-text">account_circle</mat-icon>
</mat-form-field>
<mat-form-field appearance="outline" fxFlex="50" class="pl-4">
<mat-label>'contact.Last name' | translate</mat-label>
<input matInput formControlName="lastname">
<mat-icon matSuffix class="secondary-text">account_circle</mat-icon>
</mat-form-field>
</div>
<div fxLayout="row wrap" fxLayoutAlign="start center" fxFlex="1 0 auto">
<mat-form-field appearance="outline" fxFlex="100" class="pl-4">
<mat-label>'contact.Mail' | translate</mat-label>
<input matInput formControlName="email">
<mat-icon matSuffix class="secondary-text">mail</mat-icon>
</mat-form-field>
</div>
<div fxLayout="row wrap" fxLayoutAlign="start center" fxFlex="1 0 auto">
<mat-form-field appearance="outline" fxFlex="100" class="pl-4">
<mat-label>Groupe AD</mat-label>
<input matInput formControlName="group" required [pattern]="groupPattern">
<mat-icon matSuffix class="secondary-text">group</mat-icon>
<mat-error *ngIf="group.errors?.required">'contact.Groupe AD is required!' | translate
</mat-error>
<mat-error *ngIf="group.errors?.pattern">'contact.Groupe AD is not Valid!' | translate
</mat-error>
</mat-form-field>
</div>
<div formArrayName="requested_domains"
*ngFor="let domain of form.controls.requested_domains.controls; let i = index" fxLayout="row wrap"
fxLayoutAlign="start center" fxFlex="1 0 auto">
<div [formGroupName]="i" fxLayout="row" fxLayoutAlign="start center" fxFlex="1 0 auto">
<mat-form-field appearance="outline" fxFlex="40" class="pl-4">
<mat-label>Domaines</mat-label>
<input matInput formControlName="domain_name" required [pattern]="domainPattern">
<mat-error *ngIf="requested_domains.errors?.required">
'contact.Groupe AD is required!' | translate</mat-error>
<mat-error *ngIf="requested_domains.errors?.pattern">
'contact.Groupe AD is not Valid!' | translate</mat-error>
</mat-form-field>
<!-- <mat-form-field appearance="outline" fxFlex="30" class="pl-4">
<mat-label>Right</mat-label>
<mat-select placeholder="Right" formControlName="right" required>
<mat-option value="R">R</mat-option>
<mat-option value="RW">RW</mat-option>
</mat-select>
</mat-form-field> -->
<mat-radio-group formControlName="right" aria-label="Select an option" appearance="outline" fxFlex="40" class="pl-4" required>
<mat-radio-button style="font-size : 11px; margin-left: 10px" value="R">'contact.READ' | translate</mat-radio-button>
<mat-radio-button style="font-size : 11px; margin-left: 10px" value="RW">'contact.READ/WRITE' | translate</mat-radio-button>
</mat-radio-group>
</div>
<mat-icon title="Ajouter" fxFlex="10" mat-icon-button color="basic" (click)="addDomaines()" style="color:#3c5d80; cursor: pointer">add_circle</mat-icon>
<mat-icon *ngIf="form.controls.requested_domains.controls.length > 1" title="Supprimer" fxFlex="10"
mat-icon-button color="basic" (click)="deleteRow(i)" style="color:#dd2d2d; cursor: pointer">delete_forever</mat-icon>
</div>
<div fxLayout="row wrap" fxLayoutAlign="start center" fxFlex="1 0 auto">
<mat-form-field appearance="outline" fxFlex="100" class="pl-4">
<mat-label>Message</mat-label>
<input matInput formControlName="comment">
<mat-icon matSuffix class="secondary-text">message</mat-icon>
</mat-form-field>
</div>
<div fxLayoutAlign="end center">
<button mat-raised-button color="primary" [disabled]="form.invalid" (click)="Envoyer()">'contact.Envoyer'
| translate </button>
</div>
</form>
<pre>form.value | json</pre>
</div>
</div>
<ngx-spinner bdColor="rgba(51, 51, 51, 0.8)" size="medium" color="#fff" type="ball-clip-rotate"></ngx-spinner>
</div>
这是我的代码 TS:
import Component, OnInit, ChangeDetectorRef from '@angular/core';
import FormBuilder, FormGroup, Validators, FormArray from '@angular/forms';
import Subject from 'rxjs';
import FuseTranslationLoaderService from '@fuse/services/translation-loader.service';
import locale as english from 'app/pages/contact/i18n/en';
import locale as french from 'app/pages/contact/i18n/fr'
import User from 'app/models/user.model';
import inject from '@angular/core/testing';
import AuthService from 'app/services/auth.service';
import takeUntil from 'rxjs/operators';
import ToastrService from 'ngx-toastr';
import NgxSpinnerService from 'ngx-spinner';
@Component(
selector: 'app-contact',
templateUrl: './contact.component.html',
styleUrls: ['./contact.component.scss']
)
export class ContactComponent implements OnInit
form: FormGroup;
domaines : FormArray;
user: User;
domainPattern = /^(?!:\/\/)([a-zA-Z0-9-]+\.)0,5[a-zA-Z0-9-][a-zA-Z0-9-]+\.[a-zA-Z]2,64?$/;
groupPattern = /^[a-zA-Z_]+$/;
// Private
private _unsubscribeAll: Subject<any>;
/**
* Constructor
*
* @param FormBuilder _formBuilder
*/
constructor(
private _formBuilder: FormBuilder,
private _fuseTranslationLoaderService: FuseTranslationLoaderService,
private _authService: AuthService,
private cdref: ChangeDetectorRef,
private toastr: ToastrService,
private spinner: NgxSpinnerService
)
// Set the private defaults
this._unsubscribeAll = new Subject();
this._fuseTranslationLoaderService.loadTranslations(english, french);
ngAfterContentChecked()
this.cdref.detectChanges();
// -----------------------------------------------------------------------------------------------------
// @ Lifecycle hooks
// -----------------------------------------------------------------------------------------------------
/**
* On init
*/
ngOnInit(): void
// Reactive Form
this.form = this._formBuilder.group(
firstname: [''],
lastname: [''],
email: [''],
group: ['', Validators.required],
requested_domains:this._formBuilder.array([this.initItemRows()]),
comment: ['',],
);
this._authService.getAuthStatusListener()
.pipe(takeUntil(this._unsubscribeAll))
.subscribe((user) =>
this.user = user;
if(user)
this.form.patchValue(
firstname: user.first_name,
lastname:user.last_name,
email:user.user_email
)
);
/**
* On destroy
*/
ngOnDestroy(): void
// Unsubscribe from all subscriptions
this._unsubscribeAll.next();
this._unsubscribeAll.complete();
get primaryEmail()
return this.form.get('email');
get requested_domains()
return this.form.get('requested_domains');
get group()
return this.form.get('group')
initItemRows() : FormGroup
return this._formBuilder.group(
domain_name: [''],
right:['']
);
Envoyer()
const form = this.form.value;
this.spinner.show();
this._authService.formulaire(form).subscribe(res =>
this.spinner.hide();
this.toastr.success("Your form has been successfully sent");
,
error =>
this.toastr.error("Your form has not been sent");
setTimeout(() =>
/** spinner ends after 5 seconds */
this.spinner.hide();
, 1000);
);
addDomaines()
this.domaines = this.form.get('requested_domains') as FormArray;
this.domaines.push(this.initItemRows());
deleteRow(index: number)
this.domaines.removeAt(index);
请帮助解决此问题,感谢您抽出宝贵时间解决此问题
【问题讨论】:
Disable Input fields in reactive form的可能重复 是的,我尝试了这个,但是当我这样做并发送我的表单时,它不会发送在 json 上禁用的输入 然后:***.com/questions/1355728/… 在表单对象(angular.io/api/forms/FormGroup#getrawvalue)中使用getRawValue()
方法
【参考方案1】:
您不应该将disabled
与响应式表单一起使用。相反,将逻辑放在代码后面(ts文件):
this.form.get('lastname').disable();
// this.form.get('lastname').enable();
请注意,这些方法具有可选参数来控制您是否要触发更改事件 (this.form.get('lastname').valueChanges
),这是默认行为。
关于您的问题(我稍后在 cmets 上就知道了):您可以使用 this.form.getRawValue()
检索所有字段值(包括禁用的字段值)。查看文档:https://angular.io/api/forms/FormGroup#getrawvalue
实际上,正如@jo_va 所说,也许readonly
字段更适合获得您想要的东西(尽管您无法从FormControl
对象控制它)。
【讨论】:
【参考方案2】:请为您的输入控件添加只读属性。
[readonly]="true"
【讨论】:
【参考方案3】:如果您禁用表单中的某个字段,该字段将不会在生成的 JSON 中发送。如果您想禁止用户输入但仍希望将值包含在表单对象中,则必须将该字段标记为只读:
<input matInput formControlName="lastname" [readonly]="true">
总结:
使用 readonly 属性来防止用户更改控件值,但您仍希望表单对象中的值。
使用 disabled 属性来防止用户更改控件值并且您不希望表单对象中的值。
【讨论】:
如果您不想评估何时将字段设为只读,只需添加不带括号或值的 readonly 属性就足够了。以上是关于禁用角度形式的输入的主要内容,如果未能解决你的问题,请参考以下文章