Assim ele não funciona.
<input
matInput
[formControlName]="'quantidadeEstoque'"
[readonly]="ver"
(change)="calculoCustoQuantidadeEstoque()"
currencyMask
[options]="{
prefix: '',
suffix: '',
thousands: '.',
decimal: ',',
precision: 5
}"
/>
Só funciona assim:
<input
matInput
[formControlName]="'quantidadeEstoque'"
[readonly]="ver"
(ngModelChange)="calculoCustoQuantidadeEstoque()"
currencyMask
[options]="{
prefix: '',
suffix: '',
thousands: '.',
decimal: ',',
precision: 5
}"
/>
O que preciso é que quando ele sai do componente ele chama o metodo calculoCustoQuantidadeEstoque() e não quando digita algo
change é um evento do DOM, enquanto que ngModelChange é um evento do angular, amarrado ao model. Prefira ngModelChange
.
1 curtida
entendi.
Mas como fazer para utilizar o (change)=“calculoCustoQuantidadeEstoque()”, neste caso ?
O (change)=“calculoCustoQuantidadeEstoque()”, só funciona se o componente ficar assim.
<input
matInput
[formControlName]=“‘quantidadeEstoque’”
[readonly]=“ver”
(change)=“calculoCustoQuantidadeEstoque()”
/>
Mas no meu caso preciso que o campo só aceite casas decimais com até 5 caracteres.
Estou com um problema assim:
Ao digitar no campo Quantidade de venda ele altera o quantidade de estoque, ele chama este método:
HTML
>
<mat-label>Quantidade de venda *</mat-label>
<input
matInput
[formControlName]="'quantidadeVenda'"
[readonly]="ver"
currencyMask
[options]="{
prefix: '',
suffix: '',
thousands: '.',
decimal: ',',
precision: 5
}"
(ngModelChange)="calculoCustoQuantidadeVenda($event)"
/>
<mat-icon
*ngIf="inserir"
matSuffix
style="cursor: pointer"
pTooltip="Digitando a quantidade de venda o valor do campo Quantidade de estoque é alterado !"
>
info
</mat-icon>
</mat-form-field>
typescript
async calculoCustoQuantidadeVenda(valor: any): Promise<any> {
this.temUnidadePorDerivacao = false;
this.formGroup.controls.quantidadeEstoque.disable();
this.calculouValor = false;
await this.novoFormGroupValorPraticado();
if (
valor !== undefined &&
valor !== null &&
valor !== "" &&
valor !== 0 &&
this.formGroup.controls.custo.value !== undefined &&
this.formGroup.controls.custo.value !== null &&
this.formGroup.controls.custo.value !== "" &&
this.formGroup.controls.custo.value !== 0 &&
this.formGroup.controls.quantidadeVenda.status === "VALID"
) {
const quantidade = await this.calculoDerivacao(true);
this.formGroup.controls.quantidadeEstoque.setValue(quantidade);
this.formGroup.controls.quantidadeEstoque.enable();
this.formGroup.controls.quantidadeVenda.enable();
await this.ajusteTela();
} else {
this.formGroup.controls.quantidadeEstoque.enable();
await this.ajusteTela();
}
}
Ao digitar no campo Quantidade de estoque ele altera o quantidade de venda, com este método:
HTML
<mat-form-field class="w-full sm:w-60 mt-4 sm:mt-0 sm:ml-4">
<mat-label>Quantidade de estoque *</mat-label>
<input
matInput
[formControlName]="'quantidadeEstoque'"
[readonly]="ver"
currencyMask
[options]="{
prefix: '',
suffix: '',
thousands: '.',
decimal: ',',
precision: 5
}"
(ngModelChange)="calculoCustoQuantidadeEstoque($event)"
/>
<mat-icon
*ngIf="inserir"
matSuffix
style="cursor: pointer"
pTooltip="Digitando a quantidade de estoque o valor do campo Quantidade de venda é alterado !"
>
info
</mat-icon>
</mat-form-field>
typescript
async calculoCustoQuantidadeEstoque(valor: any): Promise<any> {
this.temUnidadePorDerivacao = false;
this.formGroup.controls.quantidadeVenda.disable();
this.calculouValor = false;
await this.novoFormGroupValorPraticado();
if (
valor !== undefined &&
valor !== null &&
valor !== "" &&
valor !== 0 &&
this.formGroup.controls.custo.value !== undefined &&
this.formGroup.controls.custo.value !== null &&
this.formGroup.controls.custo.value !== "" &&
this.formGroup.controls.custo.value !== 0 &&
this.formGroup.controls.quantidadeEstoque.status === "VALID"
) {
const quantidade = await this.calculoDerivacao(false);
this.formGroup.controls.quantidadeVenda.setValue(quantidade);
this.formGroup.controls.quantidadeVenda.enable();
this.formGroup.controls.quantidadeEstoque.enable();
await this.ajusteTela();
} else {
this.formGroup.controls.quantidadeVenda.enable();
await this.ajusteTela();
}
}
calculoDerivacao
private async calculoDerivacao(inverso: boolean): Promise<number>{
let quantidade: number = 0;
if("SIM" === this.produtoDerivacaoEscolhido.configuracao.calculaPrecoDimensao
&& (
this.produtoDerivacaoEscolhido.configuracao.idUnidadeMedidaFatoracaoSegunda !== undefined ||
this.produtoDerivacaoEscolhido.configuracao.idUnidadeMedidaFatoracaoSegunda !== null ||
this.produtoDerivacaoEscolhido.configuracao.idUnidadeMedidaFatoracaoSegunda !== ""
)&& (
this.produtoDerivacaoEscolhido.configuracao.tipoConversaoUnidadeSegunda !== undefined ||
this.produtoDerivacaoEscolhido.configuracao.tipoConversaoUnidadeSegunda !== null ||
this.produtoDerivacaoEscolhido.configuracao.tipoConversaoUnidadeSegunda !== ""
)&& (
this.produtoDerivacaoEscolhido.configuracao.valorConversaoUnidadeSegunda !== undefined ||
this.produtoDerivacaoEscolhido.configuracao.valorConversaoUnidadeSegunda !== null ||
this.produtoDerivacaoEscolhido.configuracao.valorConversaoUnidadeSegunda !== "" ||
this.produtoDerivacaoEscolhido.configuracao.valorConversaoUnidadeSegunda > 0
)){
if("MULTIPLICAR" === this.produtoDerivacaoEscolhido.configuracao.tipoConversaoUnidadeSegunda){
if(inverso){
quantidade = this.formGroup.controls.quantidadeVenda.value / this.produtoDerivacaoEscolhido.configuracao.valorConversaoUnidadeSegunda;
} else {
quantidade = this.formGroup.controls.quantidadeVenda.value * this.produtoDerivacaoEscolhido.configuracao.valorConversaoUnidadeSegunda;
}
} else if("DIVISAO" === this.produtoDerivacaoEscolhido.configuracao.tipoConversaoUnidadeSegunda){
if(inverso){
quantidade = this.formGroup.controls.quantidadeVenda.value * this.produtoDerivacaoEscolhido.configuracao.valorConversaoUnidadeSegunda;
} else {
quantidade = this.formGroup.controls.quantidadeVenda.value / this.produtoDerivacaoEscolhido.configuracao.valorConversaoUnidadeSegunda;
}
} else if("SOMAR" === this.produtoDerivacaoEscolhido.configuracao.tipoConversaoUnidadeSegunda){
if(inverso){
quantidade = this.formGroup.controls.quantidadeVenda.value - this.produtoDerivacaoEscolhido.configuracao.valorConversaoUnidadeSegunda;
} else {
quantidade = this.formGroup.controls.quantidadeVenda.value + this.produtoDerivacaoEscolhido.configuracao.valorConversaoUnidadeSegunda;
}
} else if("SUBTRAIR" === this.produtoDerivacaoEscolhido.configuracao.tipoConversaoUnidadeSegunda){
if(inverso){
quantidade = this.formGroup.controls.quantidadeVenda.value + this.produtoDerivacaoEscolhido.configuracao.valorConversaoUnidadeSegunda;
} else {
quantidade = this.formGroup.controls.quantidadeVenda.value - this.produtoDerivacaoEscolhido.configuracao.valorConversaoUnidadeSegunda;
}
} else {
quantidade = this.formGroup.controls.quantidadeVenda.value;
}
}
return quantidade;
}
Só que fica no looping eterno. Como resolver ?
Entendi. Nesse como o evento está aplicado aos dois inputs e um acaba alterando o outro, acaba entrando em loop mesmo. Nunca cai nesse caso, não sei se o angular tem algum mecanismo pronto para tratar essa situação. Pensei em algumas alternativas:
- Talvez vc possa fazer algum controle usando uma variável extra, por exemplo, indicando que está editando o campo A e que o evento do campo B seja ignorado e vice-e-versa
- Outra forma poderia tentar usar o evento blur para disparar apenas qdo sair do campo
- Ou ainda, poderia ter um botão calcular, por exemplo, para executar a lógica em vez de ficar apegado aos eventos.
DICA: Crie uma função de validação para dá uma reduzida no código:
isValid(valor: any): boolean {
return valor !== undefined && valor !== null && valor !== ""
}
Assim em todo lugar onde estiver fazendo essas verificações, apenas chame: isValid(qualquerValor)
. Vc tambem pode simplificar apenas com:
if (valor && valor !== 0) {}
que tb funciona.
Dei uma refatorada (com certeza dá para ser melhorado). Veja o que tu acha:
async calculoDerivacao(inverso: boolean): Promise<number> {
let quantidade: number = 0;
if (
"SIM" === this.produtoDerivacaoEscolhido.configuracao.calculaPrecoDimensao
&& this.isValid(this.produtoDerivacaoEscolhido.configuracao.idUnidadeMedidaFatoracaoSegunda)
&& this.isValid(this.produtoDerivacaoEscolhido.configuracao.tipoConversaoUnidadeSegunda)
&& (this.isValid(this.produtoDerivacaoEscolhido.configuracao.valorConversaoUnidadeSegunda) || this.produtoDerivacaoEscolhido.configuracao.valorConversaoUnidadeSegunda > 0)
) {
quantidade = this.calcular(
this.produtoDerivacaoEscolhido.configuracao.tipoConversaoUnidadeSegunda,
inverso,
this.formGroup.controls.quantidadeVenda.value,
this.produtoDerivacaoEscolhido.configuracao.valorConversaoUnidadeSegunda
)
}
return quantidade;
}
private calcular(tipoConversao: string, inverso: boolean, valueA: number, valueB: number): number {
if (tipoConversao === "MULTIPLICAR") {
return inverso ? (valueA / valueB) : (valueA * valueB);
}
if (tipoConversao === "DIVISAO") {
return inverso ? (valueA * valueB) : (valueA / valueB);
}
if (tipoConversao === "SOMAR") {
return inverso ? (valueA - valueB) : (valueA + valueB);
}
if (tipoConversao === "SUBTRAIR") {
return inverso ? (valueA + valueB) : (valueA - valueB);
}
return valueA;
}
private isValid(valor: any): boolean {
return valor !== undefined && valor !== null && valor !== ""
}
1 curtida