在Angular中的INPUT元素中使用ngModel中的管道

时间:2016-09-22 15:17:16

标签: angular pipe html-input angular2-ngmodel

我有一个HTML INPUT字段。

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

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

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

并收到错误消息:

  

动作表达式中没有管道

如何在此上下文中使用管道?

7 个答案:

答案 0 :(得分:154)

您无法在模板声明中使用Template expression operators(管道,保存导航器):

(ngModelChange)="Template statements"

(ngModelChange)=&#34; item.value | useMyPipeToFormatThatValue = $事件&#34;

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

  

与模板表达式一样,模板语句使用的语言   看起来像JavaScript。模板语句解析器与   模板表达式解析器,特别支持两者基本   赋值(=)和链接表达式(带;或,)。

     

但是,某些JavaScript语法不允许

     
      
  •   
  • 递增和递减运算符,++和 -
  •   
  • 运算符赋值,例如+ =和 - =
  •   
  • 按位运算符|和&amp;
  •   
  • 模板表达式运算符
  •   

所以你应该写如下:

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

<强> Plunker Example

答案 1 :(得分:92)

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

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

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

有关详细信息,请参阅Angular Template Syntax

答案 2 :(得分:6)

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

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

关于addToAmount的功能 - &gt;更改模糊导致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();
  }

答案 3 :(得分:4)

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

我想再增加一个点。

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

记住它并节省时间。

答案 4 :(得分:0)

我的解决方案如下所示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">

答案 5 :(得分:0)

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

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

答案 6 :(得分: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);
}

如果有更好的解决方案来防止出现此错误,那就更好了。