禁用角度形式的输入

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 属性就足够了。

以上是关于禁用角度形式的输入的主要内容,如果未能解决你的问题,请参考以下文章

以角度形式形成输入数组

如何将元素更改为角度形式的输入或下拉菜单?

markdown 角度 - 具有多输入场的材料形式

如何将元素更改为以角度形式输入或下拉?

以角度形式将输入创建为数组

在角度形式指令的单元测试中设置视图值输入字段