为了账号安全,请及时绑定邮箱和手机立即绑定

如何在自动完成组件中显示焦点和模糊的不同值

如何在自动完成组件中显示焦点和模糊的不同值

噜噜哒 2021-08-26 20:18:46
我试图显示不同的值取决于焦点/模糊自动完成输入。假设我们对每个项目都有id和的项目有建议desc。我想通过id和过滤项目desc。当我选择其中之一并且输入模糊时,应该有id并desc显示(例如 1 - item01)。当焦点回到输入上时,它应该只显示id(没有desc),如果有任何建议id(比如 10 在那里,它应该建议 1010 | desc )。现在我必须强行擦除desc才能回到id. 不应该是这样。感谢您的任何建议。查看图像上的预期行为:
查看完整描述

2 回答

?
largeQ

TA贡献2039条经验 获得超7个赞

控制值存取器 (CVA)

该ControlValueAccessor界面是你在找什么。


为什么?该接口将 DOM 与 Angular Form 分离,允许显示下拉和输入与表单实际使用的值不同。


您可以将自定义输入实现为单独的组件*并传入 FormControl。


以下是未经测试的工作 Stackblitz


*编辑 3 - 我相信也可以将其作为指令来实现。请参阅 - 实现 ControlValueAccessor 的 Angular 2 指令不会在更改时更新“已触摸”属性


黑匣子外

你的app.component.html最终看起来像。


<form class="example-form">

  <app-auto-special [users]="options" [formControl]="myControl"></app-auto-special>

</form>

app-auto-special就像一个黑匣子,它只关心用户 ID。


我们可以 patchValue 或 setValue ,它会做它的事情(在内部调用writeValue)。如果我们与该组件交互,我们将获得 FormControl 值的用户 ID。


编辑- 没有什么能阻止你传递整个 User 对象。我假设 OP 基于这个问题想要 id。


编辑 2 - 传递用户对象而不是工作 Stackbliz 的示例


黑匣子里面

我们需要使用 NG_VALUE_ACCESSOR将app-auto-special组件注册为 controlValueAccessor 的提供者。这是通过以下方式完成的:


  providers: [{

    provide: NG_VALUE_ACCESSOR,

    useExisting: forwardRef(() => AutoSpecialComponent),

    multi: true

  }]

所以在黑盒子里我们实现了由 4 个方法组成的接口:


writeValue(obj: any): void

registerOnChange(fn: any): void

registerOnTouched(fn: any): void

setDisabledState(isDisabled: boolean)?: void

这通常意味着以下样板:


export class AutoSpecialComponent implements ControlValueAccessor {

  public _value: number;

  public disabled: boolean;

  onChanged: any = () => {};

  onTouched: any = () => {};


  /*

  * ControlValueAccessor boilerplate

  *

  */

  writeValue(value): void {

    this._value = value

  }

  registerOnChange(fn: any): void {

    this.onChanged = fn;

  }

  registerOnTouched(fn: any): void {

    this.onTouched = fn;

  }

  setDisabledState(isDisabled: boolean): void {

    this.disabled = isDisabled

  }


}

我们制作了registerOnChangeand提供的函数的副本,并在我们想要更新 formControl 值或它在 touch 属性上时registerOnTouched调用这些副本(this.onChanged和this.onTouched)。setDisabledState是可选的,writeValue在初始化时或当我们从父级调用patchValue或时调用setValue。


要设置我们调用的 FormControl this.onChanged(some_value);,我们可以挂钩各种事件input, focusin, blur,optionSelected并决定分别发生什么:


表单控件值

显示哪些选项

输入中应该是什么显示字符串

这个答案附带了一个警告,即这是我完成的第一个 CVA 实现之一,所以我在基础上摇摇欲坠。


额外的好处

单元测试 - 独立的 DOM 显示与表单

逻辑分离——父级不再饱和


查看完整回答
反对 回复 2021-08-26
  • 2 回答
  • 0 关注
  • 171 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信