【问题标题】:Empty dropdown selected value空下拉选择值
【发布时间】:2018-08-04 07:27:50
【问题描述】:

我正在使用 Angular5 和 primeng 库。特别是,我对 p-dropdown 有疑问。我有一个大实体——寄售——有很多字段,我用这个保存的对象打开页面。并且几个 p-dropdown 元素(这里是合约组件)不显示选定的值。但是,我确信没有对象的空字段。当与 p-dropdown ngModel 相关的 @Input() 字段不存在时,与 p-dropdown options 属性链接的数组似乎仍然为空。如何在启动 ngModel 字段之前填写选项数组?或者可能还有其他问题?我的代码如下:

HTML模板:

<div class="form-group ui-float-label">
  <p-dropdown [options]="selectItems" [(ngModel)]="contract" [filter]="true" (onChange)="onContractSelect()"
              [style]="{'width':'100%'}" id="contract" placeholder="Select a contract" [required]="required" ></p-dropdown>
  <label for="contract" [hidden]="contract == null">Contract</label>
</div>

组件代码:

export class SelectContractComponent implements OnChanges{
  public contracts : Contract[] = [];
  @Input() contract: Contract;
  @Output() contractChange = new EventEmitter();
  @Input() contractor: Contractor;
  selectItems: SelectItem[]= [];

  @Input() disabled: boolean;
  @Input() required: boolean;

  constructor(
    private contractService: ContractService) {
  }


  ngOnChanges(changes: SimpleChanges): void {
    this.getAllContracts();
    const contractor: SimpleChange = changes.contractor;
    this.selectItems = [];
    if (contractor != null && contractor.currentValue != null){
      this.getContractsByContractor();
    }
  }

  private fillSelectItems(contract: Contract){
    this.selectItems.push({label: contract.name, value: contract});
  }

  getContractsByContractor():void {
    this.contractService.getContractsByContractor(this.contractor.id)
      .subscribe(contracts => {
        this.contracts = contracts;
        this.contracts.forEach(c => this.fillSelectItems(c));
      });
  }

  getAllContracts():void{
    this.contractService.getContracts()
      .subscribe(contracts => {
        this.contracts = contracts;
        this.contracts.forEach(c => this.fillSelectItems(c));
      });
  }

  public onContractSelect(){
    this.contractChange.emit(this.contract);
  }

}

寄售模板的片段:

<app-select-contract [(contract)]="consignment.costPayerContract" [contractor]="consignment.costPayer"
                                     *ngIf="consignment.costPayer"></app-select-contract>

【问题讨论】:

    标签: angular dropdown primeng


    【解决方案1】:

    我找到了解决方案。我必须为 ngModel 创建一个字段,并在填写 selectItems 后将此字段分配给合同的字段。

    HTML模板:

    <div class="form-group ui-float-label">
      <p-dropdown [options]="selectItems" **[(ngModel)]="selectedItem"** [filter]="true" (onChange)="onContractSelect()"
                  [style]="{'width':'100%'}" id="contract" placeholder="Select a contract" [required]="required" ></p-dropdown>
      <label for="contract" [hidden]="contract == null">Contract</label>
    </div>
    

    组件类:

    export class SelectContractComponent implements OnChanges{
      public contracts : Contract[] = [];
      @Input() contract: Contract;
      @Output() contractChange = new EventEmitter();
      @Input() contractor: Contractor;
      selectItems: SelectItem[] = [];
      **selectedItem: Contract;**
    
      @Input() disabled: boolean;
      @Input() required: boolean;
    
      constructor(
        private contractService: ContractService) {
      }
    
      ngOnChanges(changes: SimpleChanges): void {
        console.log('select contract on changes');
        const contractor: SimpleChange = changes.contractor;
        if (contractor != null && contractor.currentValue != null){
          this.getContractsByContractor();
        } else {
          this.getAllContracts();
        }
        console.log('select contract on changes end');
      }
    
      getContractsByContractor():void {
        this.contractService.getContractsByContractor(this.contractor.id)
          .subscribe(contracts => {
            this.contracts = contracts;
            this.fillSelectItems();
            console.log('before assign selected item');
            **this.selectedItem = this.contract;**
          });
      }
    
      getAllContracts():void{
        this.contractService.getContracts()
          .subscribe(contracts => {
            this.contracts = contracts;
            this.fillSelectItems();
            console.log('before assign selected item');
            **this.selectedItem = this.contract;**
          });
      }
    
      public onContractSelect(){
        this.contractChange.emit(this.selectedItem);
      }
    
      fillSelectItems():void{
        console.log('filling select items');
        this.selectItems = [];
        this.contracts.forEach(c => this.selectItems.push({label: c.name, value: c}));
        console.log('filling select items end');
      }
    
    }
    

    【讨论】:

      【解决方案2】:

      我在primeng的代码中发现了一个竞争条件,如果你设置你的选项,然后在之后(在同一个线程/函数中)设置你的selectedOption,它将无法用你的selectedOption更新显示。 一个快速的解决方法是在设置选项之后添加一个 observable(在设置 selectedOption 之前给他们时间更新他们的数据)

      public randomSetFunction(options: any, selectedOption: any) {
          this.options = options;
          of(this.options).subscribe(opts => { this.selectedOption = selectedOption });
      }
      

      这个问题可能会在Primeng的更高版本中修复(我用7.1.3测试过)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-03-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多