根据最初检查的复选框值在后退按钮单击时重新加载 Angular 6 反应式表单

Posted

技术标签:

【中文标题】根据最初检查的复选框值在后退按钮单击时重新加载 Angular 6 反应式表单【英文标题】:Reload Angular 6 reactive form on back button click based on checkbox values checked initially 【发布时间】:2019-06-30 23:50:00 【问题描述】:

在我的反应形式中,我在复选框中加载资产。单击提交按钮时,值将传递给 _dataService 服务类,并在路由到的下一个表单“表单”上检索。用户可以从“表单”按下后退按钮,当此表单重新加载时,它应该能够填充最初检查的值。我能够在 this.dataProcessDetail.selectedAssets 中正确地从 _dataService 检索值,但是,我不知道如何检查复选框。我猜如何将它们设置为真或假。这是完整的示例代码:

模板:

<form [formGroup]="processDetailsForm" (ngSubmit)="submit()" *ngIf="isFormReady">

    <div class="row">

        <div class="form-group">
            <label class="col-sm-12 control-label">
                Select 
            </label>
            <div class="col-xs-4" formArrayName='assets'
                 *ngFor="let option of processDetailsForm.controls.assets.controls; let i = index">
                <input [formControlName]="i" type="checkbox" /> assets[i].option
            </div>
        </div>
    </div>

    <div class="form-group">
        <div class="row">
            <button type="submit" id="btnNext" class="btn btn-primary" [disabled]="processDetailsForm.invalid">
                Next >
            </button>
        </div>
    </div>
</form>

和组件:

import  Component, OnInit  from '@angular/core';
import  ReactiveFormsModule, FormBuilder, FormGroup, FormArray, FormControl, ValidatorFn  from '@angular/forms';
import  DataService  from '../../services/data.service';
import  Router  from '@angular/router';

@Component(
    selector: 'app-reports',
    templateUrl: './reports.component.html',
    styleUrls: ['./reports.component.scss']
)
export class ReportsComponent implements OnInit 
    processDetailsForm: FormGroup;
    isFormReady: boolean = false;
    private selectedAssets;
    public dataProcessDetail;
    assets = [
         id: 1, option: 'chk 1' ,
         id: 2, option: 'chk 2' ,
         id: 3, option: 'chk 3' ,
         id: 4, option: 'chk 4' ,
         id: 5, option: 'chk 5' ,
         id: 6, option: 'chk 6' 
    ]; 
    constructor(private formBuilder: FormBuilder, private _dataService: DataService,
         private _router: Router)  

    ngOnInit() 
        this.LoadControls();
        if (this._dataService.getBtnOption() === 'Back') 
            this.ReloadProcessDetails();
        
        // this.LoadContactStreamsAssets();

    
    submit() 
         this.selectedAssets = this.processDetailsForm.value.assets
            .map((v, i) => v ? this.assets[i] : null)
            .filter(v => v !== null);

        this.dataProcessDetail = 
            'selectedAssets': this.selectedAssets

        
        this._dataService.setBtnOption('btnNextORBack', 'Next');

        this._dataService.setOptionProcessDetails('dataProcessDetail', this.dataProcessDetail);
        this._router.navigate(['forms']);
    
    ReloadProcessDetails() 
        this.dataProcessDetail = this._dataService.getOptionProcessDetails();
        for (var i = 0; i < this.dataProcessDetail.selectedAssets.length; i++) 
            this.processDetailsForm.controls['assets'].setValue(
                this.processDetailsForm.controls['assets'].value
                    .map(value => this.dataProcessDetail.selectedAssets[i].option)
            );
            
    
    LoadControls() 
        const controls = this.assets.map(c => new FormControl(true));
        this.processDetailsForm = this.formBuilder.group(
            assets: new FormArray(controls)
        );
        this.isFormReady = true;

    

..和data.service.ts

import  Injectable  from '@angular/core';

@Injectable(
    providedIn: 'root',
)
export class DataService 
    public btnData: string;
    public processData: any = null;

    setOptionProcessDetails(option, value) 
        this.processData = value;
    
    getOptionProcessDetails() 
        return this.processData;
    
    setBtnOption(option, value) 
        this.btnData = value;
    
    getBtnOption() 
        return this.btnData;
    

  

【问题讨论】:

【参考方案1】:

只需将表单的值存储在您的服务中,然后使用patchValue

submit() 
    this.selectedAssets = this.processDetailsForm.value;
    ...

ReloadProcessDetails() 
    this.dataProcessDetail = this._dataService.getOptionProcessDetails();
    this.processDetailsForm.patchValue(this.dataProcessDetail.selectedAssets);

Here is a slightly modified version of your example。保存 -> 更改复选框 -> 重新加载

【讨论】:

我已编辑帖子以完成示例。请指导 我更新了答案,因为现在问题更清楚了。不过下次尽量简化代码。【参考方案2】:

您使用以下方法修补复选框值。

   ReloadProcessDetails() 
    this.dataProcessDetail = this._dataService.getOptionProcessDetails();
    this.processDetailsForm = this.formBuilder.group(
        assets:  this.formBuilder.array(this.assets.map(x => 
      this.dataProcessDetail.selectedAssets.indexOf(x.option) > -1))
    );
        

【讨论】:

没用!在初始表单加载时,默认情况下会检查所有复选框,因为我有我想要的 FormControl(true),但是当我转到下一页并返回此表单时,所有复选框都未选中。

以上是关于根据最初检查的复选框值在后退按钮单击时重新加载 Angular 6 反应式表单的主要内容,如果未能解决你的问题,请参考以下文章

单击 Safari 上的后退按钮时使用 React 挂钩强制页面重新加载

如何取消选中后退按钮上的复选框?

复选框仍然选中点击后退按钮,但它没有“选中”属性

在浏览器后退按钮上自动重新加载POST请求

按下后退按钮时正在重新创建 Listview 片段

使用浏览器后退按钮时如何强制重新加载页面?