最初加载现有选项失败

时间:2019-11-27 18:21:14

标签: angular typescript angular-forms

(现有iu.unit的初始加载失败:

 <select id="unit" name="unit" #unit="ngModel" class="form-control" 
     [(ngModel)]="iu.unit" (change)="onDropdownChangeUnit(rec,iu)">
     <option *ngFor="let i of UI_Units" [ngValue]="i">{{i.name}}</option>
 </select>

它显示了unit中的所有UI_Units,但没有显示iu.unit的初始值。

我错了什么?

已更新

结构上,我在所有foreach上都使用了ingridientUnit => iu,尝试为其分配初始值。

但是,当用户想要更改-UI_Units => coming from backend(asp.net Core)-时,应将其重新分配给iu.unit

export class Recipe{

    id: string;

    ingridientUnit: IngridientUnit[] // iu

    // ...
}


export class IngridientUnit {

    id: string;

    unit: Unit[]

    // ...
}

export class Unit {

    id: string;
    name: string;

    // ...
}

从服务器获取:

 getUnits(filter: ServerRequest) {
    return this._http.get(this.myAppUrl + 'Unit/GetUnits' + '?' + this.toQueryString(filter))
        .pipe(map((res: Unit[]) => { return res; }));
}

1 个答案:

答案 0 :(得分:0)

首先,select仅在下拉列表中显示其子项option

由于这个原因,iu.unit必须在UI_Units中,否则默认情况下将不选择任何内容,并且iu.unit的选项不会出现在列表中。

我们可以在此检查Angular Forms' code,我想将您的注意力集中到第134行writeValue和第178行_getOptionId

writeValue(value: any): void {
  this.value = value;
  const id: string|null = this._getOptionId(value);
  // excerpt only
}

_getOptionId(value: any): string|null {
  for (const id of Array.from(this._optionMap.keys())) {
    if (this._compareWith(this._optionMap.get(id), value)) return id;
  }
  return null;
}
当使用writeValue将值传递到元素中时,会调用

ngModel,然后在包含所有子选项的映射中查找该值。如果找不到代表该值的选项(在您的情况下为iu.unit),则不会发生任何有意义的事情。

最重要的是,该选项默认情况下不会出现在select元素下,仅当它明确包含在模板中时才会显示。

我已经创建了a working example个您要完成的工作,请注意iu.unit是数组UI_Units中的一个元素。 its comparison algorithm work就是这样。