Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

1.6K
Visualizações
Cómo usar tuberías en la entrada de forma reactiva Angular 5

Estoy tratando de descubrir cómo usar una tubería dentro de una forma reactiva para que la entrada se fuerce en un formato de moneda. Ya creé mi propia tubería para esto, la cual probé en otras áreas del código, así que sé que funciona como una tubería simple. Mi nombre de tubería es 'udpCurrency'

La respuesta más cercana que pude encontrar en el desbordamiento de pila fue esta: Uso de tuberías dentro de ngModel en elementos INPUT en Angular2-View Sin embargo, esto no funciona en mi caso y sospecho que tiene algo que ver con el hecho de que mi forma es reactiva

Aquí está todo el código relevante:

La plantilla

 <form [formGroup]="myForm" #f="ngForm"> <input class="form-control col-md-6" formControlName="amount" [ngModel]="f.value.amount | udpCurrency" (ngModelChange)="f.value.amount=$event" placeholder="Amount"> </form>

El componente

 import { Component, OnInit, HostListener } from '@angular/core'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; export class MyComponent implements OnInit { myForm: FormGroup; constructor( private builder: FormBuilder ) { this.myForm = builder.group({ amount: ['', Validators.required] }); } }

El error:

 ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'undefined: '. Current value: 'undefined: undefined'
over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

Esto es lo que puede suceder cuando mezclas formularios basados en plantillas y formularios reactivos. Tienes dos ataduras luchando entre sí. Elija una forma basada en plantillas o reactiva. Si desea seguir la ruta reactiva, puede usar [value] para su canalización...

Tenga en cuenta que esta tubería es más bien solo para mostrar la salida deseada en la vista.

 <form [formGroup]="myForm"> <input [value]="myForm.get('amount').value | udpCurrency" formControlName="amount" placeholder="Amount"> </form>
over 4 years ago · Santiago Trujillo Relatório

0

Pensé que esto funcionaba, pero resultó que estaba equivocado (y acepté una respuesta incorrecta). Acabo de rehacer mi lógica de una manera nueva que funciona mejor para mí y responde a la preocupación de Jacob Roberts en los comentarios anteriores. Aquí está mi nueva solución:

La plantilla:

 <form [formGroup]="myForm"> <input formControlName="amount" placeholder="Amount"> </form>

El componente:

 import { Component, OnInit, HostListener } from '@angular/core'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { UdpCurrencyMaskPipe } from '../../../_helpers/udp-currency-mask.pipe'; export class MyComponent implements OnInit { myForm: FormGroup; constructor( private builder: FormBuilder, private currencyMask: UdpCurrencyMaskPipe, ) { this.myForm = builder.group({ amount: ['', Validators.required] }); this.myForm.valueChanges.subscribe(val => { if (typeof val.amount === 'string') { const maskedVal = this.currencyMask.transform(val.amount); if (val.amount !== maskedVal) { this.myForm.patchValue({amount: maskedVal}); } } }); } }

El tubo:

 import { Pipe, PipeTransform } from '@angular/core'; @Pipe({ name: 'udpCurrencyMask' }) export class UdpCurrencyMaskPipe implements PipeTransform { amount: any; transform(value: any, args?: any): any { let amount = String(value); const beforePoint = amount.split('.')[0]; let integers = ''; if (typeof beforePoint !== 'undefined') { integers = beforePoint.replace(/\D+/g, ''); } const afterPoint = amount.split('.')[1]; let decimals = ''; if (typeof afterPoint !== 'undefined') { decimals = afterPoint.replace(/\D+/g, ''); } if (decimals.length > 2) { decimals = decimals.slice(0, 2); } amount = integers; if (typeof afterPoint === 'string') { amount += '.'; } if (decimals.length > 0) { amount += decimals; } return amount; } }

Ahora hay varias cosas que aprendí aquí. Una era que lo que dijo Jacob era cierto, la otra forma solo funcionó inicialmente pero no se actualizaría cuando el valor hubiera cambiado. Otra cosa muy importante a tener en cuenta es que necesito un tipo de tubería completamente diferente para una máscara en comparación con una tubería de visualización. Por ejemplo, una canalización en una vista podría tomar este valor "100" y convertirlo en "$100,00". Por esta razón, creé mi tubería de máscara de moneda que simplemente elimina los números no numéricos y restringe el decimal a dos lugares.

over 4 years ago · Santiago Trujillo Relatório

0

Iba a escribir un control personalizado, pero descubrí que anular el "onChange" de la clase FormControl a través de ngModelChange era más fácil. emitViewToModelChange: false es fundamental durante la lógica de actualización para evitar bucles recurrentes de eventos de cambio. Toda la canalización a la moneda ocurre en el componente y no tiene que preocuparse por los errores de la consola.

 <input matInput placeholder="Amount" (ngModelChange)="onChange($event)" formControlName="amount" />
 @Component({ providers: [CurrencyPipe] }) export class MyComponent { form = new FormGroup({ amount: new FormControl('', { validators: Validators.required, updateOn: 'blur' }) }); constructor(private currPipe:CurrencyPipe) {} onChange(value:string) { const ctrl = this.form.get('amount') as FormControl; if(isNaN(<any>value.charAt(0))) { const val = coerceNumberProperty(value.slice(1, value.length)); ctrl.setValue(this.currPipe.transform(val), { emitEvent: false, emitViewToModelChange: false }); } else { ctrl.setValue(this.currPipe.transform(value), { emitEvent: false, emitViewToModelChange: false }); } } onSubmit() { const rawValue = this.form.get('amount').value; // if you need to strip the '$' from your input's value when you save data const value = rawValue.slice(1, rawValue.length); // do whatever you need to with your value } }
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda