Existe uma maneira de usar funções matemáticas nas ligações do AngularJS?
por exemplo
<p>The percentage is {{Math.round(100*count/total)}}%</p>
Este violino mostra o problema
Existe uma maneira de usar funções matemáticas nas ligações do AngularJS?
por exemplo
<p>The percentage is {{Math.round(100*count/total)}}%</p>
Este violino mostra o problema
<p>The percentage is {{(100*count/total)| number:0}}%</p>
mais nos comentários abaixo.private Math = Math;
e você pode usá-lo.Respostas:
Você precisa injetar
Math
no seu escopo, se não precisar usá-lo, pois$scope
não sabe nada sobre matemática.Maneira mais simples, você pode fazer
no seu controlador. Uma maneira angular de fazer isso corretamente seria criar um serviço de matemática, eu acho.
fonte
formatting
, então use o filtro.Enquanto a resposta aceita é correta, você pode injetar
Math
para usá-la em ângulo, para esse problema em particular, a maneira mais convencional / angular é o filtro numérico:Você pode ler mais sobre o
number
filtro aqui: http://docs.angularjs.org/api/ng/filter/numberfonte
{{1234.567|number:2}}
processa como1,234.57
ou1 234,57
. Se você tentar passá-lo,<input type="number" ng-value="1234.567|number:2">
você esvaziará a entrada, pois o valor NÃO É UM NÚMERO CORRETO, mas a representação de sequência dependente da localidade.Eu acho que a melhor maneira de fazer isso é criando um filtro, assim:
então a marcação fica assim:
Violino atualizado: http://jsfiddle.net/BB4T4/
fonte
Essa é uma pergunta difícil de responder, porque você não deu o contexto completo do que está fazendo. A resposta aceita funcionará, mas em alguns casos causará baixo desempenho. Isso, e será mais difícil de testar.
Se você estiver fazendo isso como parte de um formulário estático, tudo bem. A resposta aceita funcionará, mesmo que não seja fácil de testar, e seja hinky.
Se você deseja ser "angular" sobre isso:
Você deseja manter qualquer "lógica comercial" (isto é, lógica que altera os dados a serem exibidos) fora de suas visualizações. Isso é para que você possa testar sua lógica de unidade e não acabar acoplando firmemente seu controlador e sua visão. Teoricamente, você deve poder apontar seu controlador para outra visão e usar os mesmos valores dos escopos. (se isso faz sentido).
Você também deve considerar que todas as chamadas de função dentro de uma ligação (como
{{}}
oung-bind
oung-bind-html
) terão que ser avaliadas em todos os resumos , porque o angular não tem como saber se o valor foi alterado ou não como uma propriedade no escopo.A maneira "angular" de fazer isso seria armazenar em cache o valor em uma propriedade no escopo da mudança usando um evento ng-change ou mesmo um $ watch.
Por exemplo, com um formulário estático:
E agora você pode testá-lo!
fonte
$window
vez que parece funcionar apenas com um planoMath.round()
?Math
testes. Como alternativa, você pode criar um serviço de matemática e injetá-lo.Por que não agrupar todo o objeto de matemática em um filtro?
e usar:
{{number_var | math: 'ceil'}}
fonte
Melhor opção é usar:
Ele define o valor padrão da equação como 0 no caso em que os valores não são inicializados.
fonte
Se você deseja fazer uma rodada simples em Angular, pode definir facilmente o filtro dentro de sua expressão. Por exemplo:
{{ val | number:0 }}
Veja este exemplo do CodePen e para outras opções de filtro numérico.
Documentos angulares sobre o uso de filtros numéricos
fonte
A maneira mais fácil de fazer contas simples com o Angular é diretamente na marcação HTML para ligações individuais, conforme necessário, supondo que você não precise fazer cálculos em massa na sua página. Aqui está um exemplo:
Nesse caso, basta fazer as contas em () e usar um filtro | para obter uma resposta numérica. Veja mais informações sobre a formatação de números angulares como texto:
https://docs.angularjs.org/api/ng/filter
fonte
Ligue o objeto Math global ao escopo (lembre-se de usar $ window not window)
Use a ligação no seu HTML:
Ou crie um filtro para a função matemática específica que você procura:
Use o filtro no seu HTML:
fonte
Isso não parece uma maneira muito angular de fazer isso. Não sei ao certo por que isso não funciona, mas você provavelmente precisará acessar o escopo para usar uma função como essa.
Minha sugestão seria criar um filtro. Essa é a maneira angular.
Então, no seu HTML, faça o seguinte:
fonte
O
number
filtro formata o número com separadores de milhares, portanto, não é estritamente uma função matemática.Além disso, o seu 'limitador' decimal não
ceil
decimais cortados (como algumas outras respostas levariam você a acreditar), mas simround
preenchê-los.Portanto, para qualquer função matemática que você desejar, você pode injetá-la (mais fácil de zombar do que injetar todo o objeto Math) da seguinte maneira:
Também não é necessário envolvê-lo em outra função.
fonte
Este é mais ou menos um resumo de três respostas (de Sara Inés Calderón, klaxon e Gothburz), mas como todas adicionaram algo importante, considero que vale a pena juntar as soluções e acrescentar mais explicações.
Considerando o seu exemplo, você pode fazer cálculos no seu modelo usando:
No entanto, isso pode resultar em muitas casas decimais, portanto, usar filtros é um bom caminho a seguir:
Por padrão, o filtro numérico deixará até três dígitos fracionários ; é nesse ponto que o argumento da fraçãoSize é bastante útil (
{{ 100 * (count/total) | number:fractionSize }}
), que no seu caso seria:Isso também arredondará o resultado já:
Mostrar snippet de código
A última coisa a mencionar, se você confiar em uma fonte de dados externa, provavelmente é uma boa prática fornecer um valor de fallback adequado (caso contrário, você poderá ver NaN ou nada no seu site):
Nota: Dependendo das suas especificações, você pode até ser mais preciso com seus fallbacks / definir fallbacks em níveis mais baixos (por exemplo
{{(100 * (count || 10)/ (total || 100) | number:2)}}
). No entanto, isso nem sempre faz sentido ..fonte
Exemplo de texto datilografado angular usando um pipe.
math.pipe.ts
Adicionar às declarações @NgModule
use no seu modelo da seguinte maneira:
fonte