如何在自动完成组件中显示焦点和模糊的不同值 [英] how to display different values on focus and on blur in autocomplete component

查看:15
本文介绍了如何在自动完成组件中显示焦点和模糊的不同值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图根据焦点/模糊自动完成输入显示不同的值.

假设我们对每个项目都有 iddesc 的项目有建议.我想按 iddesc 过滤项目.当我选择其中之一并且输入模糊时,应该显示 iddesc(例如 1 - item01).

当焦点回到输入上时,它应该只显示 id(没有 desc),如果有任何关于 id 的建议(比如 if 10是否应该建议 1010 | desc ).现在我必须强行擦除 desc 才能回到 id.不应该是这样.

感谢您的任何建议.

您可以尝试编辑

解决方案

Control Value Accessor (CVA)

ControlValueAccessor 界面正是您所需要的.

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

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

以下是未经测试的正在运行的 Stackblitz

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

<小时>

黑匣子之外

您的 app.component.html 最终会看起来像.

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

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

我们可以使用 patchValue 或 setValue 来完成它的工作(在内部调用 writeValue).如果我们与该组件交互,我们将获得 FormControl 值的用户 ID.

编辑 - 没有什么能阻止您传递整个 User 对象.根据问题,我假设 OP 想要 id.

Edit 2 - 示例传递 User 对象而不是 工作 Stackbliz

<小时>

黑匣子内

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

 提供者:[{提供:NG_VALUE_ACCESSOR,useExisting: forwardRef(() => AutoSpecialComponent),多:真}]

因此在黑盒中我们实现了由 4 个方法组成的接口:

  1. writeValue(obj: any): void
  2. registerOnChange(fn: any): void
  3. registerOnTouched(fn: any): void
  4. setDisabledState(isDisabled: boolean)?: void

这通常意味着以下样板:

导出类 AutoSpecialComponent 实现 ControlValueAccessor {公共_值:数字;公共禁用:布尔值;onChanged: any = () =>{};onTouched: any = () =>{};/** ControlValueAccessor 样板**/写值(值):无效{this._value = 值}registerOnChange(fn: any): void {this.onChanged = fn;}registerOnTouched(fn: any): void {this.onTouched = fn;}setDisabledState(isDisabled: boolean): void {this.disabled = isDisabled}}

我们复制了 registerOnChangeregisterOnTouched 提供的函数,并调用这些副本(this.onChangedthis.onTouched) 当我们想要更新 formControl 值或者它在 touch 属性上.setDisabledState 是可选的,writeValue 在初始化时或当我们从父级调用 patchValuesetValue 时调用.>

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

  • FormControl 值
  • 显示哪些选项
  • 输入中应该是什么显示字符串
<小时>

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

<小时>

额外好处

  • 单元测试 - 独立的 DOM 显示与表单
  • 逻辑分离——父级不再饱和

资源

通过以下 YouTube 视频了解更多信息控制值访问器 |詹妮弗·瓦德拉

随附以下幻灯片

I'm trying to display different value depends on focus/blur autocomplete input.

Let's say we have suggestions of items where each item has id and desc. I want to filter items by id and by desc. When I select one of them and input is blur there should be id and desc displayed (e.g. 1 - item01).

When focus is back on input it should display only id (without desc) and if any suggestions with that id(like if 10 is there it should suggest 1010 | desc ). Right now I have to forcefully erase the desc to get back to id. That shouldn't be the case.

Thanks for any suggestions.

You can try to edit this example

See expected behavior on image:

解决方案

Control Value Accessor (CVA)

The ControlValueAccessor interface is what you are looking for.

Why? This interface decouples the DOM from the Angular Form allowing the display drop down and input to differ from the value that is actually used by the form.

You can implement a custom input as a separate component* and pass a FormControl in.

The following is an untested Working Stackblitz

*Edit 3 - I believe it may also possible to implement this as a directive. See - Angular 2 Directive implementing ControlValueAccessor doesn't update 'touched' property on change


Outside the black box

Your app.component.html will end up looking like.

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

app-auto-special acts like a blackbox where it cares only about the User id.

We can patchValue or setValue and it will do it's thing (call writeValue internally). If we interact with this component we get User id's for the FormControl value.

Edit - nothing is stopping you passing the whole User object around instead. I'm assumed OP wanted id based on the question.

Edit 2 - Example passing User object instead Working Stackbliz


Inside the black box

We need to register the app-auto-special component as a provider for the controlValueAccessor using NG_VALUE_ACCESSOR. This is done via:

  providers: [{
    provide: NG_VALUE_ACCESSOR,
    useExisting: forwardRef(() => AutoSpecialComponent),
    multi: true
  }]

So inside the black box we implement the interface comprising of 4 methods:

  1. writeValue(obj: any): void
  2. registerOnChange(fn: any): void
  3. registerOnTouched(fn: any): void
  4. setDisabledState(isDisabled: boolean)?: void

This usually means the following boilerplate:

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
  }

}

We make a copies of the functions provided by registerOnChange and registerOnTouched and call these copies (this.onChanged and this.onTouched) when we want to update the formControl value or it's on touched property. setDisabledState is optional and writeValue is called on initialization or when we call patchValue or setValue from the parent.

To set the FormControl we call this.onChanged(some_value); and we can hook into various events input, focusin, blur, optionSelected and decide what happens separately to:

  • The FormControl value
  • Which options to show
  • What display string should be in the input

This answer comes with the caveat that this is one of the first CVA implementations I've done so I'm shaky on the foundations.


Additional benefits

  • Unit testing - isolated DOM display versus form
  • Separation of logic - parent no longer saturated

Resources

Learn more from the following youtube video The Control Value Accessor | Jennifer Wadella

This is accompanied by the following slides

这篇关于如何在自动完成组件中显示焦点和模糊的不同值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆