AngularJS bağlarında matematik fonksiyonlarını kullanmanın bir yolu var mı?
Örneğin
<p>The percentage is {{Math.round(100*count/total)}}%</p>
Bu keman sorunu gösteriyor
private Math = Math;
ve onu kullanın.
AngularJS bağlarında matematik fonksiyonlarını kullanmanın bir yolu var mı?
Örneğin
<p>The percentage is {{Math.round(100*count/total)}}%</p>
Bu keman sorunu gösteriyor
private Math = Math;
ve onu kullanın.
Yanıtlar:
Eğer Matematik hakkında hiçbir şey bilmiyor Math
gibi kullanmak gerekiyorsa, kapsam içine enjekte etmek zorunda
$scope
.
En basit yol, yapabilirsin
$scope.Math = window.Math;
kontrolörünüzde. Bunu doğru bir şekilde yapmanın açısal yolu bir Matematik hizmeti oluşturmak olurdu sanırım.
formatting
, bu nedenle filtre kullanın.
Kabul edilen cevap, Math
açısal olarak kullanmak için enjekte edebileceğiniz doğru olsa da , bu özel sorun için, daha geleneksel / açısal yol sayı filtresidir:
<p>The percentage is {{(100*count/total)| number:0}}%</p>
number
Filtre hakkında daha fazla bilgiyi buradan edinebilirsiniz: http://docs.angularjs.org/api/ng/filter/number
{{1234.567|number:2}}
olarak işler . Bunu iletmeye çalışırsanız , değer DOĞRU BİR NUMARAL DEĞİLDİR, ancak yerel ayara bağlı dize temsili olduğundan girdiyi boşaltırsınız. 1,234.57
1 234,57
<input type="number" ng-value="1234.567|number:2">
Bunu yapmanın en iyi yolunun böyle bir filtre oluşturarak olduğunu düşünüyorum:
myModule.filter('ceil', function() {
return function(input) {
return Math.ceil(input);
};
});
işaretleme şöyle görünür:
<p>The percentage is {{ (100*count/total) | ceil }}%</p>
Güncellenmiş keman: http://jsfiddle.net/BB4T4/
Bu cevap verilecek tüylü bir soru, çünkü ne yaptığınızın tam bağlamını vermediniz. Kabul edilen cevap işe yarayacaktır, ancak bazı durumlarda düşük performansa neden olacaktır. Bunu test etmek daha zor olacak.
Bunu statik bir formun parçası olarak yapıyorsanız, iyi. Kabul edilen cevap, test edilmesi kolay olmasa bile işe yarayacaktır ve hinky.
Herhangi bir "iş mantığını" (yani görüntülenecek verileri değiştiren mantığı) görünümlerinizin dışında tutmak istersiniz. Bu, mantığınızı birim olarak test edebilmeniz için kontrol cihazınızı ve görüşünüzü sıkıca birleştirmezsiniz. Teorik olarak, kontrol cihazınızı başka bir görünüme yönlendirebilmeniz ve kapsamlardaki aynı değerleri kullanabilmeniz gerekir. (Mantıklı geliyorsa).
Ayrıca, bir bağlamanın içindeki ( {{}}
veya ng-bind
veya ng-bind-html
) herhangi bir işlev çağrısının her özette değerlendirilmesi gerekeceğini düşünmek isteyeceksiniz , çünkü açısal değerin bir özellikte değişip değişmediğini bilmiyor kapsamda.
Bunu yapmanın "açısal" yolu, bir ng-change olayı veya hatta $ watch kullanarak değişiklik kapsamındaki bir özellikteki değeri önbelleğe almak olacaktır.
Örneğin statik bir formla:
angular.controller('MainCtrl', function($scope, $window) {
$scope.count = 0;
$scope.total = 1;
$scope.updatePercentage = function () {
$scope.percentage = $window.Math.round((100 * $scope.count) / $scope.total);
};
});
<form name="calcForm">
<label>Count <input name="count" ng-model="count"
ng-change="updatePercentage()"
type="number" min="0" required/></label><br/>
<label>Total <input name="total" ng-model="total"
ng-change="updatePercentage()"
type="number" min="1" required/></label><br/>
<hr/>
Percentage: {{percentage}}
</form>
describe('Testing percentage controller', function() {
var $scope = null;
var ctrl = null;
//you need to indicate your module in a test
beforeEach(module('plunker'));
beforeEach(inject(function($rootScope, $controller) {
$scope = $rootScope.$new();
ctrl = $controller('MainCtrl', {
$scope: $scope
});
}));
it('should calculate percentages properly', function() {
$scope.count = 1;
$scope.total = 1;
$scope.updatePercentage();
expect($scope.percentage).toEqual(100);
$scope.count = 1;
$scope.total = 2;
$scope.updatePercentage();
expect($scope.percentage).toEqual(50);
$scope.count = 497;
$scope.total = 10000;
$scope.updatePercentage();
expect($scope.percentage).toEqual(5); //4.97% rounded up.
$scope.count = 231;
$scope.total = 10000;
$scope.updatePercentage();
expect($scope.percentage).toEqual(2); //2.31% rounded down.
});
});
$window
sadece planla çalışıyor gibi göründüğünü merak ediyorsun Math.round()
?
Math
testler için alay etmenizi sağlar . Alternatif olarak, bir Matematik hizmeti oluşturabilir ve enjekte edebilirsiniz.
Neden tüm matematik nesnesini bir filtreye sarmıyorsunuz?
var app = angular.module('fMathFilters',[]);
function math() {
return function(input,arg) {
if(input) {
return Math[arg](input);
}
return 0;
}
}
return app.filter('math',[math]);
ve kullanmak için:
{{number_var | Matematik: 'ceil'}}
Açısal'da basit bir tur yapmak istiyorsanız, ifadenizdeki filtreyi kolayca ayarlayabilirsiniz. Örneğin:
{{ val | number:0 }}
Diğer sayı filtresi seçenekleri için bu CodePen örneğine ve bölümüne bakın .
Angular ile basit matematik yapmanın en kolay yolu, sayfanızda toplu hesaplamalar yapmanız gerekmediği varsayılarak, gerektiğinde tek tek ciltlemeler için doğrudan HTML biçimlendirmesidir. İşte bir örnek:
{{(data.input/data.input2)| number}}
Bu durumda, sadece () matematik yapmak ve sonra bir filtre | bir sayı cevabı almak için. Açısal sayıları metin olarak biçimlendirme hakkında daha fazla bilgi:
Genel Math nesnesini kapsama bağlayın (pencereyi değil $ penceresini kullanmayı unutmayın)
$scope.abs = $window.Math.abs;
HTML'nizdeki bağlayıcıyı kullanın:
<p>Distance from zero: {{abs(distance)}}</p>
Veya peşinde olduğunuz belirli Matematik işlevi için bir filtre oluşturun:
module.filter('abs', ['$window', function($window) {
return function(n) {
return $window.Math.abs($window.parseInt(n));
};
});
HTML'nizdeki filtreyi kullanın:
<p>Distance from zero: {{distance | abs}}</p>
Bu çok Açısal bir yol gibi görünmüyor. Neden işe yaramadığından tam olarak emin değilim, ancak böyle bir işlevi kullanmak için muhtemelen kapsama erişmeniz gerekir.
Benim önerim bir filtre oluşturmak olacaktır. Açısal yol budur.
myModule.filter('ceil', function() {
return function(input) {
return Math.ceil(input);
};
});
Ardından HTML'nizde bunu yapın:
<p>The percentage is {{ (100*count/total) | ceil }}%</p>
number
O kesinlikle bir matematik fonksiyonu değil böylece filtre, binlerce ayırıcılar ile numarayı biçimlendirir.
Dahası, ondalık 'sınırlayıcısı', ceil
kesilmiş ondalık sayılar değil (diğer bazı cevaplar sizi inanmanıza neden olacağı için) değil round
, onlara verir.
Yani istediğiniz herhangi bir matematik fonksiyonu için, onu enjekte edebilirsiniz (bütün Math nesnesini enjekte etmekten daha kolay):
myModule.filter('ceil', function () {
return Math.ceil;
});
Başka bir işleve sarmanıza gerek yok.
Bu, üç yanıtın (Sara Inés Calderón, klaxon ve Gothburz tarafından) aşağı yukarı bir özeti, ancak hepsi önemli bir şey ekledikçe, çözümlere katılmaya ve biraz daha açıklama eklemeye değer olduğunu düşünüyorum.
Örneğinizi göz önünde bulundurarak, aşağıdakileri kullanarak şablonunuzda hesaplamalar yapabilirsiniz:
{{ 100 * (count/total) }}
Bununla birlikte, bu çok sayıda ondalık basamağa neden olabilir, bu nedenle filtreleri kullanmak iyi bir yoldur:
{{ 100 * (count/total) | number }}
Varsayılan olarak, sayı filtresi en fazla üç kesirli basamak bırakacaktır , bu durumda fractionSize argümanının oldukça kullanışlı ( {{ 100 * (count/total) | number:fractionSize }}
) olduğu durumda, bu durumda:
{{ 100 * (count/total) | number:0 }}
Bu ayrıca sonucu yuvarlayacak:
Bahsetmeniz gereken son şey, bir dış veri kaynağına güveniyorsanız, uygun bir geri dönüş değeri sağlamak muhtemelen iyi bir uygulamadır (aksi takdirde sitenizde NaN veya hiçbir şey görebilirsiniz):
{{ (100 * (count/total) | number:0) || 0 }}
Sidenote: Spesifikasyonlarınıza bağlı olarak, yedeklerinizle daha hassas olabilir / daha düşük düzeylerde yedekleri tanımlayabilirsiniz (örn. {{(100 * (count || 10)/ (total || 100) | number:2)}}
). Yine de, bu her zaman anlamlı olmayabilir.
Boru kullanarak açısal dizgi örneği.
math.pipe.ts
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'math',
})
export class MathPipe implements PipeTransform {
transform(value: number, args: any = null):any {
if(value) {
return Math[args](value);
}
return 0;
}
}
@NgModule bildirimlerine ekle
@NgModule({
declarations: [
MathPipe,
ardından şablonunuzda şu şekilde kullanın:
{{(100*count/total) | math:'round'}}
<p>The percentage is {{(100*count/total)| number:0}}%</p>
daha fazla yorum aşağıda.