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

问题描述 投票:0回答:8

我有一个 HTML 输入字段。

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

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

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

并收到错误消息:

动作表达式中不能有管道

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

angular pipe html-input angular2-ngmodel
8个回答
279
投票

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

(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" />

Plunker 示例


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

这里的解决方案是将绑定分为单向绑定和事件绑定 - 语法

[(ngModel)]
实际上包含了这一点。
[]
是单向绑定语法,
()
是事件绑定语法。当一起使用时 -
[()]
Angular 将其识别为简写形式,并以单向绑定和事件绑定的形式连接到组件对象值的双向绑定。

无法将

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

请参阅 Angular 模板语法了解更多信息。


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

我想在已接受的答案的基础上再补充一点。

如果您的输入控件的类型不是文本,则管道将不起作用。

记住这一点,节省您的时间。


7
投票

我尝试了上面的解决方案,但进入模型的值是格式化的值,然后返回并给我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();
  }

2
投票

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

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


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
投票

由于是双向绑定,为了防止错误:

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);
  }  

如果有更好的解决方案来防止这个错误就好了。


0
投票

借助值和输入动态修改任何数据的方法

<input [value]="currentItem.name"
       (input)="currentItem.name=getValue($event)">
getValue(event: Event): string {
  let utcDateString = (event.target as HTMLInputElement).value;
 if (utcDateString && utcDateString.includes('000Z')) {
      const utcDate = new Date(utcDateString);
      const year = utcDate.getUTCFullYear();
      const month = String(utcDate.getUTCMonth() + 1).padStart(2, '0'); // Months are zero-based
      const day = String(utcDate.getUTCDate()).padStart(2, '0');
      utcDateString = `${year}-${month}-${day}`;
      return utcDateString;
    }
return utcDateString 
}

例如,我有一个 ISO 格式“2024-05-31T00:00:00.000Z”的日期,我想将该日期转换为“2024-05-31”,因为我直接使用我的对象数据它应该提供数据并更新同一对象数组中的数据。

dateData = [{from:"2024-05-31T00:00:00.000Z",to:"2024-05-31T00:00:00.000Z"},{from:"2024-05-31T00:00:00.000Z",to:"2024-05-31T00:00:00.000Z"}]

所以我找到的解决方案是


<div class="row" *ngFor="let season of dateData; let inx = index">
  <div class="col form-group">
    <label for="from">Start date</label>
    <input
      class="form-control"
      id="from_{{ inx }}"
      type="date"
      value="{{ season.from | date : 'yyyy-MM-dd' }}"
      (input)="season.from = getValue($event)"
      required
    />
  </div>
</div>
<div class="col-3">
  <div class="col form-group">
    <label for="to">End date</label>
    <input
      class="form-control"
      id="to_{{ inx }}"
      type="date"
      value="{{ season.to | date : 'yyyy-MM-dd' }}"
      (input)="season.to = getValue($event)"
      required
    />
  </div>
</div>

谢谢!

© www.soinside.com 2019 - 2024. All rights reserved.