在AngModel中的ngModel上的ngModel中使用管道


143

我有一个HTML INPUT字段。

<input 
    [(ngModel)]="item.value" 
    name="inputField" 
    type="text" 
/>

我想格式化其值并使用现有管道:

.... 
[(ngModel)]="item.value | useMyPipeToFormatThatValue" 
....

并得到错误信息:

动作表达式中不能有管道

在这种情况下如何使用管道?

Answers:


213

您不能在模板语句中使用模板表达式运算符(管道,保存导航器):

(ngModelChange)="Template statements"

(ngModelChange)=“ item.value | useMyPipeToFormatThatValue = $ event”

https://angular.io/guide/template-syntax#template-statements

与模板表达式一样,模板语句使用的语言类似于JavaScript。模板语句解析器不同于模板表达式解析器,并且特别支持基本赋值(=)和链接表达式(带有;或,)。

但是,某些JavaScript语法是不允许的

  • 增量和减量运算符++和-
  • 运算符分配,例如+ =和-=
  • 按位运算符| 和&
  • 模板表达式运算符

所以你应该这样写:

<input [ngModel]="item.value | useMyPipeToFormatThatValue" 
      (ngModelChange)="item.value=$event" name="inputField" type="text" />

柱塞示例


3
有人可以解释为什么必须这样拆分吗?我试图将日期绑定到类型为date的输入:[(ngModel)] =“ model.endDate | date:'y-MM-dd'”,管道将无法正常工作。但是,如果我放弃了香蕉语法并使用上面的拆分语法,则效果很好。
布莱克·里维尔

这真的有用吗?它对我不起作用。它说动作表达式中不能有管道
NoStressDeveloper

4
这对我有用!@BlakeRivell“ []”将属性从数据源单向绑定到查看目标,此时您可以更改管道显示的方式。当使用“()”绑定时,改变格式的另一种方法在这里将毫无用处。因此,我想这就是为什么“ [()]”框中的香蕉无法与管道配合使用并将其分开的方法。:你可以阅读更多关于它在这里angular.io/docs/ts/latest/guide/...
麦克Bovenlander

8
请注意,在该示例中,管道仅在一个方向上起作用。假设item.value是一个数字,您DatePipe可以将其转换为日期字符串。编辑日期后,$event还将是日期字符串,将不适合日期。item.value您必须反转(ngModelChange)表达式中管道的内容,即将日期字符串改回数字。
Tuupertunut

3
@Protagonist (ngModelChange)="updateItemValue($event)",然后创建一个updateItemValue(date: string)方法并在其中添加方法item.value = someConversionFunction(date); 现在,如果您要询问将什么用作转换函数,我不知道。也许Date.parse()可以。
Tuupertunut

111
<input [ngModel]="item.value | useMyPipeToFormatThatValue" 
      (ngModelChange)="item.value=$event" name="inputField" type="text" />

此处的解决方案是将绑定分为单向绑定和事件绑定-该语法[(ngModel)]实际上包含该绑定。[]是单向绑定语法,()是事件绑定语法。一起使用时[()]-Angular将其识别为速记,并以单向绑定和事件绑定的形式连接到双向绑定,并将事件绑定到组件对象值。

无法[()]与管道一起使用的原因是,管道仅适用于单向绑定。因此,您必须拆分管道以仅对单向绑定进行操作,并分别处理事件。

有关更多信息,请参见Angular 模板语法


1
如何添加条件表达式,如| 编号:“ 3.2-5”?
主角

14
<input [ngModel]="item.value | currency" (ngModelChange)="item.value=$event"
name="name" type="text" />

我想再增加一个要点。

如果输入控件的类型不是文本,则管道将无法工作。

请记住它并节省您的时间。


笑纳在你的答案中添加更多的信息
因德尔·

1
检查ngx-locale-mask角度库,该库是我根据角度区域设置对输入框进行屏蔽的特定货币
Tibin Thomas

6

我尝试了上面的解决方案,但是模型的值是格式化值,然后返回并给了我currencyPipe错误。所以我不得不

  [ngModel]="transfer.amount | currency:'USD':true"
                                   (blur)="addToAmount($event.target.value)"
                                   (keypress)="validateOnlyNumbers($event)"

并且在addToAmount的功能上->模糊更改会导致ngModelChange给我光标问题。

removeCurrencyPipeFormat(formatedNumber){
    return formatedNumber.replace(/[$,]/g,"")
  }

并删除其他非数字值。

validateOnlyNumbers(evt) {
  var theEvent = evt || window.event;
  var key = theEvent.keyCode || theEvent.which;
  key = String.fromCharCode( key );
  var regex = /[0-9]|\./;
  if( !regex.test(key) ) {
    theEvent.returnValue = false;
    if(theEvent.preventDefault) theEvent.preventDefault();
  }

我们还尝试了为百分比管道选择的答案,并为(ngModelChange)编写了类似于toDecimal()的方法,这两个方法相互追逐。因此您输入的数字不能超过1个数字。令人惊讶的是,它获得了如此多的好评
Angela P

1

我的解决方案在下面给出,这里searchDetail是一个对象。

<p-calendar  [ngModel]="searchDetail.queryDate | date:'MM/dd/yyyy'"  (ngModelChange)="searchDetail.queryDate=$event" [showIcon]="true" required name="queryDate" placeholder="Enter the Query Date"></p-calendar>

<input id="float-input" type="text" size="30" pInputText [ngModel]="searchDetail.systems | json"  (ngModelChange)="searchDetail.systems=$event" required='true' name="systems"
            placeholder="Enter the Systems">

0

您必须使用[ngModel]而不是使用[(ngModel)]进行双向模型绑定。然后将手动更改事件与(ngModelChange)一起使用。这是组件中所有双向输入的公共规则。

因为事件发射器上的管道是错误的。


0

由于两种方式的绑定,为防止发生以下错误:

ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was 
checked.

您可以调用一个函数来更改模型,如下所示:

<input [ngModel]="item.value" 
  (ngModelChange)="getNewValue($event)" name="inputField" type="text" />


import { UseMyPipeToFormatThatValuePipe } from './path';

constructor({
    private UseMyPipeToFormatThatValue: UseMyPipeToFormatThatValuePipe,
})

getNewValue(ev: any): any {
    item.value= this.useMyPipeToFormatThatValue.transform(ev);
}

如果有一个更好的解决方案来防止该错误,那就更好了。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.