Angular 下拉选单如何选定预设值

情境

当表单送出後,资料库会记录送出後的值,下次再进来时,会需要重现上一次所填写过的内容,这在实作上是很常遇到的事情。

解决方式

原以为这是件很简单的事,读取资料後,直接把值填上後即可(想得太简单了),
当实作时,却怎麽样也选不了预设值,後来发现在需要在 select 里 加上 compareWith 比对,下拉选单才会正确选到所设定的预设值。


实作

这里有套用到 Angular Material

以下是以复选值做范例

template

<mat-form-field>
  <mat-label>Label</mat-label>
  <mat-select multiple [formControl]="selected" [compareWith]="compareFn">
    <mat-option *ngFor="let option of options" [value]="option">
      {{ option.label }}
    </mat-option>
  </mat-select>
</mat-form-field>

component

interface option {
  label: string;
  value: string;
}

export class ExampleComponent implements OnInit {
  selected = new FormControl();

  options: option[] = [
    {
      label: "apple",
      value: "apple",
    },
    {
      label: "kiwi",
      value: "kiwi",
    },
    {
      label: "banana",
      value: "banana",
    },
    {
      label: "cherry",
      value: "cherry",
    },
  ];

  ngOnInit(): void {
    // 若 api 来的值是 fruits = ['banana', 'kiwi']
    // 先将值转为 option 格式

    // 模拟api来的值
    of(["banana", "kiwi"])
      .pipe(
        take(1),
        map((fruits: string[]) => {
          return fruits.map((e) => {
            return {
              label: e,
              value: e,
            };
          });
        })
      )
      .subscribe((options: option[]) => {
        this.selected.setValue(options);
      });
  }
  compareFn(a: option, b: option): boolean {
    return a && b ? a.value === b.value : a === b;
  }
}

若是需要单选的话,将 html 里的 multiple 移除

这里需要注意的是,FormControl 里的值,需与 options 里选单的格式是一样,值才会被正常选中


程序码解说

这里需要有 rxjs 的概念
范例使用 of 模拟 observable api 读取进来的资料
rxjs operators 的 take 执行一次後
再使用 map 转成我们需要的格式
接着再 subscribe (订阅) 出来 将值塞到 FormControl 里

范例:https://stackblitz.com/edit/angular-ivy-phixnz


参考资料:https://angular.tw/api/forms/SelectControlValueAccessor


<<:  Day 13 - 安装(三)副本调度设定

>>:  Day06 建构Project(2)

Day 26 : 插件篇 05 — 做好笔记备份,使用 Obsidian Git自动备份笔记到 Github

前言 我在《操作基础篇 04 — 做好笔记备份 ,使用 iCloud 和 Google Drive ...

【Day2】想要在铁人赛完毕前做好的简单 App

APP 点子 我这次铁人赛的目标是在30天内做个游戏化的生活管理 App,可能因为有很多 个 App...

Day 7 拖动上传图片辨识数字

今天要做的是... 做一个前端网页,支援拖动图片上传, 把图片转成 base64 送给服务器,服务器...

Netlify CMS : 完全就是为了 JAMstack 而设计的 CMS 系统

Netlify CMS 完全就是为了 JAMstack 而设计的 CMS 系统 前面分享了直接使用第...

[Day18] Webpack - 预处理器

前几天学到了 PostCSS、Babel 这些後处理器,来协助在打包时改写原始码来支援各种浏览器,今...