角度:动态形式的问题

如何解决角度:动态形式的问题

我有一个动态的子表单,即一个选择字段值更改了另一个选择字段的内容,并设置了认值(如果存在)。

从属选择选项进行了很好的更改,但修补认值不起作用...

这是.ts:

    export interface GsmattFormValues {
    id: number,mattype: number,material: number,}
@Component({
  selector: 'ngx-gsmatt',templateUrl: './gsmatt.component.html',styleUrls: ['./gsmatt.component.scss'],providers: [
    {
      provide: NG_VALUE_ACCESSOR,useExisting: forwardRef(() => GsmattComponent),multi: true
    },{
      provide: NG_VALIDATORS,multi: true
    }
  ]
})
export class GsmattComponent implements OnInit,OnDestroy,ControlValueAccessor {

  @input() inMandatoryObjects: any;
  @input() inErrors: any[];

  mattypes: Mattype[];
  materials: Material[];

  allowMaterials: boolean = false;

  destroy$: Subject<boolean> = new Subject<boolean>();

  gsmattForm: FormGroup;

  constructor(
    private formBuilder: FormBuilder,public translate: TranslateService,) { 
    }

  get f() { return this.gsmattForm.controls; }

/////////////////////////////////////////////////////////
////// OnInit & onDestroy
/////////////////////////////////////////////////////////
  ngOnInit(): void {
        this.mattypes=this.inMandatoryObjects['mattypes'];
        this.materials=this.inMandatoryObjects['materials'];
        this.initForm();
        this.gsmattForm.valueChanges.takeuntil(this.destroy$).subscribe(value => {
            this.onChange(value);
            this.onTouched();
        });
        
  }

  ngOnDestroy() {
    this.destroy$.next(true);
    this.destroy$.unsubscribe();
  }

//////////////////////////////////////////////////////////////////////////////
///// Control Value Accessor
//////////////////////////////////////////////////////////////////////////////

  get value(): GsmattFormValues {
    return this.gsmattForm.value;
  }

  set value(value: GsmattFormValues) {
    //if( value !== undefined && this.value !== value){ 
    if( value !== undefined ){      
        this.configureMatRCP(this.mattypes.find(item => item.id==value.mattype));
        this.gsmattForm.patchValue(value);
        this.onChange(value);
        this.onTouched();
    }
  }

  onChange: any = () => {}

  onTouched: any = () => {
  }

  // this method sets the value programmatically
  writeValue(value) {
    if (value) {
        this.value = value;
    }

    if (value === null) {
      this.gsmattForm.reset();
    }

  }

// upon UI element value changes,this method gets triggered
  registerOnChange(fn) {
    this.onChange = fn;
  }

// upon touching the element,this method gets triggered
  registerOnTouched(fn) {
    this.onTouched = fn;
  }

  // communicate the inner form validation to the parent form
  validate(_: FormControl) {
    return this.gsmattForm.valid ? null : { profile: { valid: false } };
  }

  get errors() {
    return this.gsmattForm.errors ? null : this.gsmattForm.errors;
  }


//////////////////////////////////////////////////////////////////////////////
///// Miscellaneous Functions
//////////////////////////////////////////////////////////////////////////////

  initForm() {
    this.gsmattForm = this.formBuilder.group({
        id: '',mattype: new FormControl('',[Validators.required,SelectedValue]),material: new FormControl(''),});
  }

/////////////////////////////////////////////////////////
////// Event Functions
/////////////////////////////////////////////////////////
  onMattypeChange(event) {
    var MATP;
    if (event) {MATP=this.mattypes.find(item => item.id==event);}
    console.log("UPDATING");
    this.configureMatRCP(MATP);
    this.setDfltValues(MATP);
  }

/////////////////////////////////////////////////////////
////// Dynamic Form Functions
/////////////////////////////////////////////////////////

  configureMatRCP(mattype?: Mattype) {
    console.log("FOrm "+JSON.stringify(this.gsmattForm.value));
    if (mattype) {
        this.materials=this.inMandatoryObjects['materials'].filter(item => item.mattype.id==mattype.id);
        if (this.materials.length>0) {
            this.gsmattForm.get("material").enable();
            this.allowMaterials=true;
        }
        else {
            this.gsmattForm.get("material").disable();
            this.allowMaterials=false;          
        }
    }
    else {
        this.allowMaterials=false;
        this.gsmattForm.get("material").disable();
    }

  }

  setDfltValues(mattype?: Mattype) {
    if (mattype) {
        var materialsTmp=this.inMandatoryObjects['materials'].filter(item => item.mattype.id==mattype.id);
        if (materialsTmp.length>0) {
            var dfltMaterial = materialsTmp.find(item => item.isdefault==true);
            console.log("DFLMATERIAL "+JSON.stringify(dfltMaterial));
            if (dfltMaterial) {console.log("BOOM "+dfltMaterial.id); 
                this.gsmattForm.patchValue({material: dfltMaterial.id});
            }
            else {this.gsmattForm.patchValue({material: ''});}
        }
        else {
            this.gsmattForm.patchValue({material: ''});     
        }
    }
    else {
        this.gsmattForm.patchValue({material: ''});
    }

  }

}

和html:

<div class="row">
  <div class="col-md-12">
    <nb-card>
      <nb-card-body>    
        <div [formGroup]="gsmattForm">
                  
          <input type="hidden" nbInput fullWidth id="id" formControlName="id"/>  
          <div class="row">
            <div class="col-sm-6">
              <div class="form-group">
                <label for="mattype" class="label">{{ 'MATTYPE' | translate }}</label>
                <nb-select id="mattype" formControlName="mattype" fullWidth status="basic"
                placeholder="{{ 'MATTYPE' | translate }}" (selectedChange)="onMattypeChange($event)">
                  <nb-option *ngFor="let option of mattypes" [value]="option.id">
                    {{ option.label | translate }}
                  </nb-option>
                </nb-select>
                <div *ngIf="f.mattype.touched && f.mattype.errors" class="invalid-Feedback d-block">
                    <div *ngIf="f.mattype.errors['required']">{{ 'FIELD_required' | translate: {field: 'MATTYPE' | translate} }}</div>
                </div>
              </div> 
            </div>
            <div class="col-sm-6" *ngIf="allowMaterials"> 
              <div class="form-group" >
                <label for="material" class="label">{{ 'MATERIAL' | translate }}</label>
                <nb-select id="material" formControlName="material" fullWidth status="{{ (f.material.errors && f.material.touched) ? 'danger': (!f.material.errors && f.material.touched) ? 'success' : 'basic' }}"
                    placeholder="{{ 'MATERIAL' | translate }}">
                    <nb-option *ngFor="let option of materials" [value]="option.id">
                        {{ option.label | translate }}
                    </nb-option>
                </nb-select>
                <div *ngIf="f.material.touched && f.material.errors" class="invalid-Feedback d-block">
                    <div *ngIf="f.material.errors['required']">{{ 'FIELD_required' | translate: {field: 'MATERIAL' | translate} }}</div>
                </div>
             </div>     
            </div>  
            </div>
        </div>      
      </nb-card-body>
    </nb-card>
  </div>
</div>

感谢您的帮助

编辑1:经过大量处理后,似乎在选择选项过滤和修补Value之间存在冲突。然后,我尝试使用回调来确保在设置值之前等待选择选项更新。

  configureMatRCP(setDfltValue: boolean,callback,mattype?: Mattype) {
    console.log("FOrm "+JSON.stringify(this.gsmattForm.value));
    if (mattype) {
        this.materials=this.inMandatoryObjects['materials'].filter(item => item.mattype.id==mattype.id);
        if (this.materials.length>0) {
            this.gsmattForm.get("material").enable();
            this.allowMaterials=true;
        }
        else {
            this.gsmattForm.get("material").disable();
            this.allowMaterials=false;          
        }

    }
    else {
        this.allowMaterials=false;
        this.gsmattForm.get("material").disable();
    }
    if(setDfltValue) {
        callback(mattype); 
    }

  }

  onMattypeChange(event) {
    var MATP;
    if (event) {MATP=this.mattypes.find(item => item.id==event);}
    console.log("UPDATING");
    this.configureMatRCP(true,this.setDfltValues(MATP),MATP);
    //this.setDfltValues(MATP);
  }

但是我得到错误回调不是函数... 我想念什么?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?