2017-11-14 1 views
3

저는 첫 번째 프로젝트에서 Angular 4를 배우기 시작했습니다. 여기에 내 문제는 모든 요소 반응식에서 비어 있거나 정의되지 않은 FormArray를 표시하지 마십시오

<form [formGroup]="varDataForm" (ngSubmit)="onSubmit()" novalidate> 
    <div formArrayName="aggLevels" 
     *ngFor="let agLevel of varDataForm.get('aggLevels')?.controls; let aggLevelId = index;"> 
     <div [formGroupName]="aggLevelId"> 
      <label>{{agLevel?.get('aggregationLevelName')?.value}}</label> 
      <div formArrayName="variableDataForLevel" 
       *ngFor="let vardata of varDataForm.get('aggLevels')?.controls[0]?.get('variableDataForLevel')?.controls; let rowIndex = index;"> 
       <div [formGroupName]="rowIndex"> 
        <select formControlName="variableDataId"> 
         <option *ngFor="let gs1 of gs1AIs" [value]="gs1.Id">{{gs1.description}}</option> 
        </select> 
        <input formControlName="value" placeholder="Valor"> 
        <div class="error" *ngIf="vardata.get('value').hasError('required') && vardata.get('value').touched"> 
         Obligatorio 
        </div> 
       </div> 
      </div> 
     </div> 
    </div> 
</form> 

이없는됩니다

Form (FormGroup) 
    | 
    --> aggLevels (FormArray) 
     | 
     --> aggregationLevelName (FormControl? I show it in a label) 
     | 
     --> variableDataForLevel (FormArray) 
      | 
      --> variableDataId (FormControl) 
      | 
      --> value (FormControl) 

이 구성 요소 HTML은 다음과 같습니다

나는 다음과 같은 구조의 형태를 보여주기 위해 반응성 양식을 만들었습니다 in variableDataForLevel FormArray. 나는 모든 요소의 끝에서 안전한 항해 연산자 ?를 추가하는 시도

ng:///AppModuleShared/VarDataComponent.ngfactory.js:49 ERROR Error: Cannot find control with path: 'aggLevels -> 1 -> variableDataForLevel -> 0'

: 나는이 메시지를받을

varDataForm.get('aggLevels')?.controls[0]?.get('variableDataForLevel')?.controls 

을하지만 난 여전히 문제를 얻는다. FormArray aggLevelsvariableDataForLevel은 인스턴스를 만들 때 인스턴스화되므로 정의되지 않았습니다.

비어있는 경우 FormArray를 표시하지 않으려면 어떻게해야합니까?

각도가 새롭고 수정 방법에 대한 지식이 거의 없습니다.

import { Component, Inject } from '@angular/core'; 
import { FormBuilder, FormGroup, FormArray, FormControl, Validators } from '@angular/forms'; 
import { Http, RequestOptions, Headers } from '@angular/http'; 
import { IProductionOrder } from '../../interfaces/productionorder.interface'; 
import { IAggLevel } from '../../interfaces/aglevel.interface'; 
import { IGS1 } from '../../interfaces/gs1.interface'; 
import { IVarData } from '../../interfaces/vardata.interface'; 

@Component({ 
    selector: 'vardata', 
    templateUrl: './vardata.component.html' 
}) 

export class VarDataComponent { 
    public productionorders: IProductionOrder[]; 
    public gs1AIs: IGS1[]; 

    public varDataForm: FormGroup = new FormGroup({}); 
    public selectedProductionOrder: string; 

    constructor(private http: Http, 
     @Inject('BASE_URL') private baseUrl: string, 
     @Inject(FormBuilder) private fb: FormBuilder) { 

     this.selectedProductionOrder = ''; 

     http.get(baseUrl + 'api/ProductionOrder/0').subscribe(result => { 
      this.productionorders = result.json() as IProductionOrder[]; 

      console.log(this.productionorders); 
     }, error => console.error(error)); 
    } 

    productionOrderChanges() { 
     if (this.selectedProductionOrder != '') { 
      let urlVarData: string = this.baseUrl + 'api/VariableData/' + this.selectedProductionOrder; 
      let urlAggLevel: string = this.baseUrl + 'api/AggregationLevelConfiguration/' + this.selectedProductionOrder; 

      this.http.get(urlAggLevel).subscribe(result => { 
       let aggLevels: IAggLevel[] = result.json() as IAggLevel[]; 

       console.log('niveles'); 
       console.log(aggLevels); 

       if ((aggLevels != null) && (aggLevels.length > 0)) { 

        this.http.get(urlVarData).subscribe(result => { 
         let varDatas: IVarData[] = result.json() as IVarData[]; 

         console.log('variable data'); 
         console.log(varDatas); 

         this.varDataForm = this.fb.group({ 
          aggLevels: this.fb.array(this.createForm(aggLevels, varDatas)) 
         }); 

        }, error => console.error(error)); 
       } 

      }, error => console.error(error)); 
     } 
     else 
      this.varDataForm = new FormGroup({}); 
    } 

    createForm(aggLevels: IAggLevel[], varDatas: IVarData[]): any[] { 
     let array: any[] = []; 

     for (let level of aggLevels) { 
      let group: FormGroup; 
      let varDataForLevel: IVarData[] = 
       varDatas.filter(v => v.aggregationLevelConfigurationId == level.aggregationLevelConfigurationId); 

      group = this.createFormGroupForLevel(level, varDataForLevel); 
      array.push(group); 
     } 

     return array; 
    } 

    createFormGroupForLevel(level: IAggLevel, varDatas: IVarData[]): FormGroup { 
     let group: FormGroup; 

     group = this.fb.group({ 
      aggregationLevelName: level.name, 
      variableDataForLevel: this.fb.array(this.createVarDataControls(varDatas)) 
     }); 

     return group; 
    } 

    createVarDataControls(varData: IVarData[]): any[] { 
     let array: any[] = []; 

     for (let vData of varData) { 
      let group: FormGroup; 

      group = this.fb.group({ 
       variableDataId: vData.variableDataId, 
       value: vData.value 
      }); 

      array.push(group); 
     } 

     return array; 
    } 



    disableSubmit() { 
     return (!this.varDataForm.valid); 
    } 

    onSubmit() { 
    } 
} 

나는이 문제에 대해 생각 : varData가 비어

createVarDataControls(varData: IVarData[]): any[] { 
    let array: any[] = []; 

    for (let vData of varData) { 
     let group: FormGroup; 

     group = this.fb.group({ 
      variableDataId: vData.variableDataId, 
      value: vData.value 
     }); 

     array.push(group); 
    } 

    return array; 
} 

경우가 Any[]을 반환하지만 그렇게하지

이 구성 요소에 대한 구성 요소의 타이프 라이터 클래스입니다 폼에 뭔가 비어있는 것을 보여주고 싶지 않기 때문에 이것을 리턴하는 것이 에러라고 생각하십시오.

을 편집하여를 입력하십시오. varData이 비어있는 경우 FormGroup을 반환해야합니다. 이것은 나를 계속하자 그러나 나는 내 질문에 대답을 생각하지 않는다 : 그와

createVarDataControls(varData: IVarData[]): any[] { 
    let array: any[] = []; 

    if ((varData == null) || (varData.length == 0)) { 
     let group: FormGroup; 

     group = this.fb.group({ 
      variableDataId: '', 
      value: '' 
     }); 

     array.push(group); 
    } 
    else { 
     for (let vData of varData) { 
      let group: FormGroup; 

      group = this.fb.group({ 
       variableDataId: vData.variableDataId, 
       value: vData.value 
      }); 

      array.push(group); 
     } 
    } 

    return array; 
} 

내가 예외를 얻을하지 않습니다하지만 두 개의 빈 컨트롤을 보여 주며, 그 싶지 않아요. 이는 문제를 식별하는 데 유용합니다.

+0

구성 요소에서 폼과 컨트롤을 초기화하는 코드를 추가 할 수 있습니까? 감사합니다 – amal

+0

@amal 내가 사용하는 Typescript 클래스로 질문을 업데이트했습니다. – VansFannel

답변

1

문제점을 발견했습니다. 나는 그것이 누군가를 도울 수 있다면 내 해결책을 원합니다.

FormArray 루프

:

<div formArrayName="variableDataForLevel" 
       *ngFor="let vardata of varDataForm.get('aggLevels')?.controls[0]?.get('variableDataForLevel')?.controls; let rowIndex = index;"> 

하지만 정확한 인은 :

<div formArrayName="variableDataForLevel" 
     *ngFor="let vardata of agLevel.get('variableDataForLevel')?.controls; let rowIndex = index;"> 

I는 agLevel으로 varDataForm.get('aggLevels')?.controls[0]? 변경했다. 해결책을 찾을 때까지

createVarDataControls(varData: IVarData[]): any[] | undefined { 
    let array: any[] = []; 

    if ((varData == null) || (varData.length == 0)) { 
     return undefined; 
    } 
    else { 
     for (let vData of varData) { 
      let group: FormGroup; 

      group = this.fb.group({ 
       aggregationLevelConfigurationId: vData.aggregationLevelConfigurationId, 
       productionOrderId: vData.productionOrderId, 
       variableDataId: vData.variableDataId, 
       value: vData.value 
      }); 

      array.push(group); 
     } 

     return array; 
    } 
} 

시도와 실패 : 그것을 표시하는 변수 데이터가없는 경우

그리고 또한 내가 정의되지 않은 반환하는 방법 createVarDataControls을 변경했습니다!

관련 문제