Angular - 如何使输入字段以百分比格式设置但在编辑时删除百分比? [英] Angular - How to make input field formated in percent but with percent removed when editing it?

查看:27
本文介绍了Angular - 如何使输入字段以百分比格式设置但在编辑时删除百分比?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试找到一种方法,在初始页面加载时以百分比(例如 97,52 %)显示 html 输入字段(通过角度服务获取到后端的数据,即可观察/订阅),但也当我编辑它时(即当引发 DOM(焦点)事件时),让这个输入字段松散它的百分比格式.

I'm trying to find a way to have a html input field displayed in percent (e.g. 97,52 %) upon initial page load (data fetched via a angular service to a backend, i.e. observable/subscribe), but also have this input field loose it's percent formating when I edit it (i.e. when DOM (focus) event is raised).

格式数据绑定到一个模型.让我们将模型字段称为 myModel.percentNumber,其中,100 %"为percentNumber=1"(69 %"为 .69,10 000 %"为 100)

The data for format is bound to a model. Let's call the model field myModel.percentNumber, where percentNumber=1 for '100 %' (.69 for '69 %' or again 100 for '10 000 %')

因此,当我单击指示97,52 %"的字段时,我希望它变为97.52",但模型中的数据绑定值应为 0.9752,因为这是我需要存储的值.

So when I click on the field indicating '97,52 %' I want it to become '97.52', but the data-bound value in the model should be 0.9752 as this is what I need to store.

该字段应该使用 ngModel 绑定.

The field sould be bound using ngModel.

注意:这应该适用于国际化,所以我不能使用基于删除空格、替换 '.' 的肮脏"解决方案.经过 ',' ...在这里你可以看到我举了一个例子,其中格式化的百分比值应该有一个逗号作为小数分隔符和一个空格作为千​​位分隔符,但这取决于用户的本地化.

Note : this should work with internationalization, so I can't use a 'diry' solution based on removing spaces, replacing '.' by ',' ... Here you can see I've taken an example where the formated percent value should have a coma as decimal separator and a space as a thousands separator, but this depends on the user's localization.

到目前为止,我已经尝试了一些方法,但都没有解决所有问题.

So far, I've tried a few things, but none solved all issues.

1) 使用 2 路绑定 作为起点,即

...但它确实会导致管道出现问题:

...but it does cause an issue with the pipe:

未捕获的错误:模板解析错误:

Uncaught Error: Template parse errors:

2) 从 2 路绑定短语法我想要长语法,即

<input [ngmodel]="myModel.percentNumber | percent:'1.2-2'" (ngModelChange)="myModel.percentNumber = $event">

这允许在初始加载时使用正确的百分比格式(在后端响应时,如果 myModel.percentNumber=0.9752,它会正确显示为97,52 %"),但是,当您单击输入来编辑它,当我希望它显示97.52"时,格式保持不变我认为解决这个问题的正确角度"方法不是添加一个(焦点)事件处理程序,我将在其中执行与 PercentPipe.transform() 相反的操作,例如类似于 PercentPipe.parse() (它不存在).这将需要为您应该具有此行为的每个字段添加一个(焦点)事件处理程序.可重用性会很低.我相信 angular Directive 方法应该更可取.

This allows to have a proper format in percent upon initial load (on response from the back-end, if myModel.percentNumber=0.9752 it is properly displayed as '97,52 %'), however, when you click on the input to edit it, the formatting stays when I would want it to display '97.52' I don't think the proper 'angular' way to address this would be to add a (focus) event handler where I would do the reverse operation than PercentPipe.transform(), e.g. something like PercentPipe.parse() (which doesn't exists). This would require to add a (focus) event handler for each field thy should have this behavior. Re-usability would be low. I believe a angular Directive approach should be preferable .

3) with an angular Directive :我用选择器 percentFormatter 和输入 percentDigits 创建了一个指令 PercentFormatterDirective> 接受与 PercentPipe 相同格式的字符串类型(即 digitInfo).一个使用示例是:

3) with an angular Directive : I created a directive PercentFormatterDirective with a selector percentFormatter and an input percentDigits of type string that would accept the same format as PercentPipe (i.e. digitInfo). A usage example would be:

我宁愿不必在 [ngModel] 中仍然使用正常"的 PercentPipe,因为它需要将 digitInfo 1.2-2 写两次(即我不想写<input percentFormatter percentDigits="1.2-2" [ngModel]="myModel.percentNumber | percent:'1.2-2'" (ngModelChange)="myModel.percentNumber = $event">

I would rather not have to still also the 'normal' PercentPipe in [ngModel] as it would require to write the digitInfo 1.2-2 twice (i.e. I don't want to have to write <input percentFormatter percentDigits="1.2-2" [ngModel]="myModel.percentNumber | percent:'1.2-2'" (ngModelChange)="myModel.percentNumber = $event">

我可以在单击输入(焦点)时设置值的格式,因为我在 PercentFormatterDirective 中实现为(焦点)事件的侦听器:

I'm able to format the value upon clicking on the input (focus) as I've implemented in my PercentFormatterDirective as listener on the (focus) event :

  @HostListener("focus", ["$event.target.value"])
  onfocus(value) {
    if (value) {
      // we have to do the oposite than the transform (e.g. we want to go from % to number)
      this.htmlInputElement.value = this.parse(value);
    }
  }

因此,当我在该字段中单击时,这会从97,52 %"变为97.52".在这里,我没有详细介绍我创建的 parse() 方法(您只需要知道它是有效的并且基于我用来获取用户本地化的 PercentPipe & 这个 find 是小数点分隔符和千位分隔符).

So this gets met from '97,52 %' to '97.52' when I click in the field. Here I don't get into details of the parse() method I've created (you just need to know that it works and is based in the PercentPipe that I use to get the users localization & this find which is the decimal separator and thousands separator).

我还可以在离开输入字段时将值格式化回百分比格式,因为我在 PercentFormatterDirective 中作为(模糊)事件的侦听器实现了:

I'm also able to format the value back with the percent format upon leaving the input field as I've implemented in my PercentFormatterDirective as listener on the (blur) event :

  @HostListener("blur", ["$event.target.value"])
  onblur(value) {
    if ((value as string).indexOf('%') === -1) {
      this.formatNumberInPercent('100for100percent');
    }
  }

所以当我离开现场时,这会从 '97.52' 到 '97,52 %' 得到满足.在这里,我没有详细介绍 formatNumberInPercent() 方法(您只需要知道它可以工作并且基于 PercentPipe.transform() 方法,但是在之前将值除以 100,因为 PercentPipe.transform() 将得到你从 '0.9752' 到 '97,52 %' 但在我的输入中我有 '97.52',这显然是用户要输入的)

So this gets met from '97.52' to '97,52 %' when I leave the field. Here I don't get into details of the formatNumberInPercent() method (you just need to know that it works and is based in the PercentPipe.transform() method but dividing the value by 100 just before as PercentPipe.transform() will get you from '0.9752' to '97,52 %' but in my input I have '97.52' which is what the user is obviously is going to input)

这个问题是在初始加载时(更准确地说,当有后端返回时,通过可观察/订阅,当设置 myModel.percentNumber 时),(焦点)或(模糊)来自 PercentFormatterDirective 的 @HostListener 被调用,因为没有用户与 DOM 交互.如果我在 PercentFormatterDirective 中添加一个 ngOnInit(),那么是的,我可以格式化绑定值(即使用我创建的名为 formatNumberInPercent('100for100percent') 的自定义方法将 '0.9752' 转换为 '97,52 %' code> 再次使用 PercentPipe.transform() 方法,但没有将值除以 100)...但是,如果我直接在组件中绑定数据,则此方法有效,ei不使用可观察/订阅.当使用 observable/subscribe(我必须使用)从后端获取答案时,PercentFormatterDirective 的 ngOnInit() 已经被执行.

This issue is that on initial load (more exactly when there is the return from back-end, via observable/subscribe, when myModel.percentNumber is set), neither the (focus) or (blur) @HostListener from the PercentFormatterDirective are called as there is no user interaction with the DOM. If I add an ngOnInit() in the PercentFormatterDirective, then YES I can format the bound values (i.e. transform '0.9752' to '97,52 %' using a custom method I created named formatNumberInPercent('100for100percent') that uses again the PercentPipe.transform() method but without dividing the value by 100)...however this work if I bind the data directly in the Component, e.i. without using observable/subscribe. When using observable/subscribe (which I have to use) to get the answer from the back-end, the ngOnInit() of the PercentFormatterDirective has already been executed.

我需要能够在获得响应(来自 observable/subscribe)时执行格式化.我曾尝试在 PercentFormatterDirective 中添加 ngOnChanges(changes: SimpleChanges)(然后使用 for (let propName in changes) 读取 SimpleChange 数组),但是我没有从 myModel.percentNumber 查看新绑定的值.似乎 ngOnChanges(changes: SimpleChanges) 只提供了一个 SimpleChange 数组,其属性与我的指令的输入(即percentDigits)相对应.

I would need to be able to execute the formating when the response (from the observable/subscribe) is obtained. I have tried adding ngOnChanges(changes: SimpleChanges) in the PercentFormatterDirective (and then read de array of SimpleChange with for (let propName in changes)), however I don't see the newly bound value from myModel.percentNumber. It seems ngOnChanges(changes: SimpleChanges) only provides an array of SimpleChange with the property corresponding my Directive's input (i.e. percentDigits).

我在指令的构造函数中注入了 private elementRef: ElementRef,但是正如我在 ngOnChanges() 中所说的那样,我无法获得 myModel.percentNumber (this.elementRef.nativeElement.value 给了我 "" 而从来没有任何值).

I have private elementRef: ElementRef injected in the Directive's constructor, but as I said from ngOnChanges() I can't get the value of myModel.percentNumber (this.elementRef.nativeElement.value gives me "" and never any value).

也许我在生命周期中还为时过早?

Maybe I am still too soon in the life cycle ?

或者也许应该采取另一种方法?

Or maybe another approach should be taken ?

如果您有任何建议,我会很高兴听到提出来!:)

If you have any advice I would be very happy to hear bring it out ! :)

推荐答案

啊!与#2 如此接近.您可以在模板中完成这一切.您可以使用 [value] 设置值作为输入 - 然后使用 (input) - 或可能 (change) 将值转换回.我认为你不能在 ngModel 中使用管道:

Ahh! so close with #2. You can do this all in the template. You can set the value using [value] just as an input - then use (input) - or possibly (change) to convert the value back. I don't think you can use pipes in ngModel:

<input type="number" [value]="myModel.percentNumber * 100" (input)="myModel.percentNumber = $event.target.value / 100">

也没有这种方式进行文本转换或 dom 操作

No text conversions or dom manipulation this way either

这篇关于Angular - 如何使输入字段以百分比格式设置但在编辑时删除百分比?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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