각도로 입력 요소의 ngModel 내에서 파이프 사용


144

HTML 입력 필드가 있습니다.

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

값을 형식화하고 기존 파이프를 사용하고 싶습니다.

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

오류 메시지가 나타납니다.

액션 표현식에 파이프를 가질 수 없습니다

이 상황에서 파이프를 어떻게 사용합니까?

답변:


215

템플릿 문 내에서 템플릿 표현식 연산자 (파이프, 저장 탐색기)를 사용할 수 없습니다 .

(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
누군가 왜 이렇게 분리해야하는지 설명 할 수 있습니까? 날짜 유형이 [(ngModel)] = "model.endDate | date : 'y-MM-dd'"인 입력에 날짜를 바인딩하려고하면 파이프가 작동하지 않습니다. 그러나 바나나 구문을 제거하고 위의 분할 구문을 사용하면 정상적으로 작동합니다.
Blake Rivell 2012 년

이것이 실제로 작동 했습니까? 그것은 나를 위해 작동하지 않았다. 그것은 행동 표현에 파이프를 가질 수 없습니다
NoStressDeveloper

4
이것은 나를 위해 일했습니다! @BlakeRivell "[]"는 데이터 소스에서 속성을 단방향으로 바인딩하여 파이프에서 표시되는 방법을 변경할 수있는 시점에서 대상을 봅니다. "()"바인딩을 사용할 때 형식을 변경하는 다른 방법은 쓸모가 없습니다. 그래서 "[()]"상자에 바나나가 파이프와 함께 작동하지 않고 분리하는 것이 좋은 방법 인 것 같습니다. 자세한 내용은 여기를 참조하십시오 : angular.io/docs/ts/latest/guide/…
Mike 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는이를 속기로 인식하고 단방향 바인딩 및 이벤트를 구성 요소 오브젝트 값에 바인딩하는 형식으로 양방향 바인딩을 연결합니다.

[()]파이프와 함께 사용할 수없는 이유 는 파이프가 단방향 바인딩에서만 작동하기 때문입니다. 따라서 단방향 바인딩에서만 작동하고 이벤트를 개별적으로 처리하려면 파이프를 분리해야합니다.

자세한 내용은 각도 템플릿 구문 을 참조하십시오.


1
다음과 같은 조건식을 추가하는 방법 | 번호 : '3.2-5'?
주인공

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

허용 된 답변에 하나 이상의 포인트를 추가하고 싶습니다.

입력 컨트롤의 유형이 텍스트가 아닌 경우 파이프가 작동하지 않습니다.

명심하고 시간을 절약하십시오.


답변에 더 많은 정보를 추가하십시오
Inder

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

또한 Percent 파이프에 대해 선택된 답변을 시도하고 (ngModelChange)에 대해 toDecimal ()과 같은 메소드를 작성했으며 두 메소드는 서로 추적합니다. 한 자리 이상 입력 할 수 없습니다. 너무 많이 찬란에 놀랐습니다
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);
}

이 오류를 방지하는 더 나은 해결책이 있다면 좋을 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.