代码之家  ›  专栏  ›  技术社区  ›  Jacopo Sciampi

NGFOR内的反应形式

  •  0
  • Jacopo Sciampi  · 技术社区  · 6 年前

    我有一个NGFOR,里面有一个反应形式。这是代码:

    <div class="element-list">
            <form [formGroup]="formGroup" class="single-item" *ngFor="let p of points; let i = index">
                <span>Lat: </span> <input formControlName="lat" type="text" value="{{p.lat}}">
                <span>Lon: </span> <input formControlName="lon" type="text" value="{{p.lon}}">
                <a (click)="updateData(i)">Submit</a>
            </form>
        </div>
    

    这是TS侧

    export class MapInfoBarComponent implements OnInit, OnDestroy
    {
      points: MapDetailModel[] = [];
      isAlive = true;
      formGroup: FormGroup;
    
    
      constructor(
        private mapService: MapService,
        private fb: FormBuilder
        ){}
    
      ngOnInit() {
    
        this.mapService.pointsChanged
        .takeWhile(() => this.isAlive)
        .subscribe( evt => {
          if(!!evt){
            this.points = evt;
          }
        });
    
        this.formGroup = this.fb.group({
          lat: new FormControl(),
          lon: new FormControl()
        });
      }
    
    
      ngOnDestroy(): void {
        this.isAlive = false;
      }
    
      updateData(id: number){
        console.log(id + " > " + this.formGroup.value);
      }
    }
    

    每当我点击 a 我从中得到了什么 this.formGroup.value 只是空值和空值。

    问题

    我的问题是,每当我单击一个按钮时,如何“知道”我指的是哪个窗体组? this.points 有时会改变,从另一个组件推送新元素。

    例如,我想更新第三个元素,并在 console.log 更新的值。

    感谢您的帮助。谢谢。

    我是如何解决这个问题的

    感谢@ak.leimrey通过下面的链接。

    我是这样解决的:

    TS文件:

    export class MapInfoBarComponent implements OnInit, OnDestroy
    {
      points: MapDetailModel[] = [];
      isAlive = true;
      survey: FormGroup;
      items = false;
    
      constructor(
        private mapService: MapService,
        private fb: FormBuilder
        ){}
    
      ngOnInit() {
    
    
    
        this.mapService.pointsChanged
        .takeWhile(() => this.isAlive)
        .subscribe( evt => {
          if(!!evt){
            this.points = evt;
    
            if(!this.items){
              this.survey = this.fb.group({
                sections: this.fb.array([
                  this.initSection(0),
                ]),
              });
              this.items = true;
            } else {
              this.addSection(this.points.length - 1);
            }
          }
        });
      }
    
    
      initSection(idx: number) {
        return this.fb.group({
          lat: [this.points[idx].lat],
          lon: [this.points[idx].lon],
        })
      }
    
      addSection(idx: number) {
        const control = <FormArray>this.survey.get('sections');
        control.push(this.initSection(idx));
      }
    
      getSections(form) {
        //console.log(form.get('sections').controls);
        return form.controls.sections.controls;
      }
    
      updateData(index: number){
        const values = this.survey.value.sections[index] as MapDetailModel;
        this.mapService.setChangePoint(values);
      }
    
      ngOnDestroy(): void {
        this.isAlive = false;
      }
    }
    

    HTML文件:

    <div class="main-wrapper">
        <div class="map-info-bar">
            <div class="blocco-info">
                {{lang.phrase('Coord')}}: {{lang.phrase('Lat')}} {{currentLatitude}} {{lang.phrase('Lon')}} {{currentLongitude}}
            </div>
            <div class="blocco-info">
                <dx-select-box [items]="zoomLevels" [value]="scale" (onValueChanged)="onScaleChange($event.value)">
                </dx-select-box>
            </div>
        </div>
    
        <div class="element-list">
            <form [formGroup]="survey" novalidate (ngSubmit)="onSubmit(survey)" *ngIf="items">
                <div formArrayName="sections">
                    <div class="single-item" *ngFor="let section of getSections(survey); let i = index">
                        <div  [formGroupName]="i">
                            <input type="text" formControlName="lat" class="frm-txt">
                            <input type="text" formControlName="lon" class="frm-txt">
                            <a (click)="updateData(i)">Update data</a>
                        </div>
                    </div>
                </div>
            </form>
        </div>
    </div>
    

    班级:

    export class MapDetailModel{
        lat: number;
        lon: number;
        alt: number;
        long?: number;
    }
    
    3 回复  |  直到 6 年前
        1
  •  1
  •   ak.leimrey    6 年前

    我讨厌做那种人,但我觉得这个代码示例不仅能解释嵌套表单的工作方式,而且还能解释如何引用表单中的单个项。

    https://stackblitz.com/edit/deep-nested-reactive-form?file=app%2Fapp.component.html

        2
  •  0
  •   George C.    6 年前

    尝试此代码可能会帮助您。 只需查看代码,然后进行更改,不要复制和粘贴 阅读

    在您的TS代码上。

    form: FormGroup;
    
    ngOnInit() {
       this.initForm():
    }
    
    initForm() {
    
         this.form = new FormGroup({
            num_weeks: new FormControl(1, []),
            metric: new FormControl('sales', []),
            statistic: new FormControl('min', []),
            filters: filters
          });
    }
    

    在HTML组件上

    <form *ngIf="form" [formGroup]="form" novalidate>
               <mat-form-field appearance="fill" floatLabel="never" style="width: 360px; font-size: 14px;">
              <mat-label>Metric</mat-label>
              <mat-select #timeRange formControlName="metric" placeholder="Time range" placeholder="Type">
                <mat-option *ngFor="let type of types" [value]="type.value">
                  {{ type.name }}
                </mat-option>
              </mat-select>
            </mat-form-field>
    
            <mat-form-field appearance="fill" floatLabel="never" style="width: 360px; font-size: 14px;">
              <mat-label>Statistic</mat-label>
              <mat-select #timeRange formControlName="statistic" placeholder="" placeholder="Statistic">
                <mat-option *ngFor="let statistic of statistics" [value]="statistic.value">
                  {{ statistic.name }}
                </mat-option>
              </mat-select>
            </mat-form-field>
    </form>
    
        3
  •  0
  •   JFPicard    6 年前

    问题可能与以下事实有关: formControlName 内部具有相同的值 ngFor .

    首先尝试:

    <span>Lat: </span> <input formControlName="lat{{i}}" type="text" value="{{p.lat}}">
    <span>Lon: </span> <input formControlName="lon{{i}}" type="text" value="{{p.lon}}">
    

    然后,创建每个 lon lat formGroup :

    this.points.forEach((point,index) => {
       this.formGroup.addControl("lat" + index, new FormControl());
       this.formGroup.addControl("lon" + index, new FormControl());
     });
    

    您将能够访问每个控件。