Sử dụng ống trong ngModel trên các phần tử INPUT trong góc


143

Tôi có một trường INPUT HTML.

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

và tôi muốn định dạng giá trị của nó và sử dụng một đường ống hiện có:

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

và nhận thông báo lỗi:

Không thể có một đường ống trong một biểu hiện hành động

Làm thế nào tôi có thể sử dụng đường ống trong bối cảnh này?

Câu trả lời:


213

Bạn không thể sử dụng toán tử biểu thức mẫu (đường ống, lưu điều hướng) trong câu lệnh mẫu:

(ngModelChange)="Template statements"

(ngModelChange) = "item.value | useMyPipeToFormatThatValue = $ event"

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

Giống như các biểu thức mẫu, các câu lệnh mẫu sử dụng một ngôn ngữ trông giống như JavaScript. Trình phân tích cú pháp câu lệnh mẫu khác với trình phân tích cú pháp biểu thức mẫu và đặc biệt hỗ trợ cả biểu thức cơ bản gán (=) và chuỗi biểu thức (với; hoặc,).

Tuy nhiên, cú pháp JavaScript nhất định không được phép :

  • Mới
  • toán tử tăng và giảm, ++ và -
  • gán toán tử, chẳng hạn như + = và - =
  • toán tử bitwise | và &
  • toán tử biểu thức mẫu

Vì vậy, bạn nên viết nó như sau:

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

Ví dụ Plunker


3
Ai đó có thể giải thích tại sao nó phải được tách ra như thế này? Tôi đang cố gắng liên kết một ngày với một đầu vào với ngày loại: [(ngModel)] = "model.endDate | date: 'y-MM-dd'" và đường ống sẽ không hoạt động. Tuy nhiên, nếu tôi bỏ đi cú pháp chuối và sử dụng cú pháp tách ra ở trên thì nó hoạt động tốt.
Blake Rivell

Điều này thực sự làm việc? nó không làm việc cho tôi nó nói Không thể có một đường ống trong một biểu hiện hành động
NoStressDeveloper

4
Điều này làm việc cho tôi để! @BlakeRivell "[]" liên kết thuộc tính một chiều từ nguồn dữ liệu để xem mục tiêu tại thời điểm đó, bạn có thể thay đổi cách hiển thị với đường ống. Khi sử dụng ràng buộc "()", cách khác là thay đổi định dạng sẽ là vô ích ở đây. Vì vậy, tôi đoán rằng đó là lý do tại sao chuối trong hộp "[()]" không hoạt động với một đường ống và tách chúng là cách để đi. Bạn có thể đọc thêm về nó ở đây: angular.io/docs/ts/latest/guide/iêu
Mike Bovenlander

8
Coi chừng trong ví dụ, đường ống chỉ hoạt động theo một hướng. Giả sử item.valuelà một số và bạn sử dụng DatePipeđể chuyển đổi nó thành chuỗi ngày. Khi ngày được chỉnh sửa, $eventđó cũng sẽ là một chuỗi ngày và sẽ không khớp với item.valueBạn phải đảo ngược những gì đường ống đã làm trong (ngModelChange)biểu thức của bạn - tức là biến chuỗi ngày trở lại thành một số.
Tuupertunut

3
@Protagonist (ngModelChange)="updateItemValue($event)", sau đó tạo một updateItemValue(date: string)phương thức và bên trong nó item.value = someConversionFunction(date); Bây giờ nếu bạn hỏi bạn nên sử dụng chức năng chuyển đổi nào, tôi không biết. Có lẽ Date.parse()có thể làm việc.
Tuupertunut

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

Giải pháp ở đây là phân chia ràng buộc thành ràng buộc một chiều và ràng buộc sự kiện - mà cú pháp [(ngModel)]thực sự bao gồm. []là cú pháp ràng buộc một chiều và ()là cú pháp ràng buộc sự kiện. Khi được sử dụng cùng nhau - [()]Angular nhận ra đây là tốc ký và nối kết liên kết hai chiều dưới dạng liên kết một chiều và liên kết sự kiện với giá trị đối tượng thành phần.

Lý do bạn không thể sử dụng [()]với đường ống là đường ống chỉ hoạt động với các ràng buộc một chiều. Do đó, bạn phải tách đường ống để chỉ hoạt động theo ràng buộc một chiều và xử lý sự kiện riêng biệt.

Xem Cú pháp mẫu Angular để biết thêm thông tin.


1
Làm cách nào để thêm biểu thức điều kiện như | số: '3.2-5'?
Nhân vật chính

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

Tôi muốn thêm một điểm nữa vào câu trả lời được chấp nhận.

Nếu loại điều khiển đầu vào của bạn không phải là văn bản, đường ống sẽ không hoạt động.

Hãy ghi nhớ và tiết kiệm thời gian của bạn.


vui lòng xem xét thêm thông tin trong câu trả lời của bạn
Inder

1
kiểm tra thư viện góc ngx-locale-mask mà tôi đã tạo để che dấu hộp nhập cho một loại tiền cụ thể dựa trên ngôn ngữ góc
Tibin Thomas

6

Tôi đã thử các giải pháp ở trên nhưng giá trị đi đến mô hình là giá trị được định dạng sau đó trả về và đưa cho tôi các lỗi tiền tệ. Vì vậy tôi đã phải

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

Và về chức năng của addToAmount -> thay đổi khi bị mờ khiến ngModelChange gây ra cho tôi các vấn đề về con trỏ.

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

Và loại bỏ các giá trị không số khác.

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

chúng tôi cũng đã thử câu trả lời được chọn cho Percent pipe và viết một phương thức như toDecimal () cho (ngModelChange) và 2 phương thức đuổi theo nhau. vì vậy bạn không thể gõ nhiều hơn 1 chữ số. đáng ngạc nhiên là nó được nâng cấp rất nhiều
Angela P

1

Giải pháp của tôi được đưa ra dưới đây tại đây searchDetail là một đối tượng ..

<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

bạn phải sử dụng [ngModel] thay vì liên kết mô hình hai chiều với [(ngModel)]. sau đó sử dụng sự kiện thay đổi thủ công với (ngModelChange). đây là quy tắc chung cho tất cả hai cách đầu vào trong các thành phần.

bởi vì đường ống trên bộ phát sự kiện là sai.


0

vì ràng buộc hai chiều, Để ngăn ngừa lỗi của:

ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was 
checked.

bạn có thể gọi một hàm để thay đổi mô hình như thế này:

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

Sẽ tốt hơn nếu có một giải pháp tốt hơn để ngăn chặn lỗi này.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.