AngularJS बाइंडिंग में गणित कार्य


232

क्या AngularJS बाइंडिंग में गणित कार्यों का उपयोग करने का एक तरीका है?

जैसे

<p>The percentage is {{Math.round(100*count/total)}}%</p>

यह फिडल समस्या को दर्शाता है

http://jsfiddle.net/ricick/jtA99/1/


11
एक अन्य विकल्प यह है कि आप अपने फिल्टर में मैथ का उपयोग करने के बजाय फ़िल्टर का उपयोग करने से बचें: <p>The percentage is {{(100*count/total)| number:0}}%</p>नीचे टिप्पणी में अधिक।
एंड्रयू कुक्लेविज़

2
Angular2 के लिए, एक घटक सदस्य को परिभाषित करें private Math = Math;और आप इसका उपयोग कर सकते हैं।
ओंद्रा Oižka

जवाबों:


329

आपको Mathअपने दायरे में इंजेक्ट करना होगा, यदि आपको इसका उपयोग करने की आवश्यकता है, तो $scopeगणित के बारे में कुछ भी नहीं पता है।

सबसे सरल तरीका, आप कर सकते हैं

$scope.Math = window.Math;

अपने नियंत्रक में। यह सही ढंग से करने के लिए कोणीय तरीका एक मैथ सर्विस बनाएगा, मुझे लगता है।


1
धन्यवाद। मेरे पास एक उपयोग का मामला है जहां मेरे पास पूरी तरह से अलग तर्क के साथ कई टेम्पलेट हैं और उन्हें यथासंभव अलग करना चाहते हैं। परफेक्ट
याब्लार्गो

48
आपको एक फ़िल्टर का उपयोग करना चाहिए, गणित की वस्तु को दायरे में नहीं रखना चाहिए।
सोवियुत

4
यह त्वरित और गंदी चीजों के लिए अच्छा है; जल्दी से कुछ का मज़ाक उड़ाते हुए या यह देखना चाहते हैं कि कुछ कैसे काम करता है। जो शायद कोई है जो अपने HTML टेम्पलेट फ़ाइलों में गणित करना चाहता है।
लैन

1
बाइंडिंग में फ़ंक्शन का उपयोग करने से फ़ंक्शन को प्रत्येक स्कोप के अपडेट में कॉल किया जा सकेगा और बहुत अधिक संसाधनों का उपयोग किया जाएगा।
देसमती २०'१६ को

यह समाधान गलत है । क्यों? 1- वैश्विक दायरे को प्रदूषित करना अब तक का सबसे बुरा विचार है। 2- विचार इसके लिए जिम्मेदार हैं formatting, इसलिए इसके बजाय फ़िल्टर का उपयोग करें।
अफशीन मेहरबानी

304

जबकि स्वीकृत उत्तर सही है कि आप Mathइसे कोणीय में उपयोग करने के लिए इंजेक्ट कर सकते हैं , इस विशेष समस्या के लिए, अधिक पारंपरिक / कोणीय तरीका संख्या फ़िल्टर है:

<p>The percentage is {{(100*count/total)| number:0}}%</p>

आप numberयहां फ़िल्टर के बारे में अधिक पढ़ सकते हैं : http://docs.angularjs.org/api/ng/filter/number


7
न केवल यह कोणीय तरीका है, यह सही तरीका है। यह मान को 'प्रारूप' करने की जिम्मेदारी है।
ल्यूक

39
एंड्रयू, इस टिप्पणी के साथ अपनी पोस्ट को अव्यवस्थित करने के लिए क्षमा करें। आपका उत्तर अच्छा और सहायक है; हालाँकि, मैं अन्य टिप्पणियों से असहमत होना चाहता हूँ। जब लोग "कोणीय तरीके" का इस्तेमाल करते हैं तो मैं अकड़ जाता हूं, क्योंकि यह सही विकास का कुछ विरोधाभास है। यह नहीं है। ओपी ने सामान्य रूप से एक बंधन में गणित के कार्यों को शामिल करने का तरीका पूछा, गोलाई के साथ केवल एक उदाहरण के रूप में प्रस्तुत किया। हालांकि यह उत्तर शुद्धतावादियों द्वारा "एक कोणीय तरीका" हो सकता है जो वास्तव में एक गणित समस्या को हल करने के लिए है, यह पूरी तरह से सवाल का जवाब नहीं देता है।
kbrimington

1
पुरातत्व के लिए क्षमा करें, लेकिन यह गलत है जब आपको आउटपुट के रूप में नंबर की आवश्यकता होती है। {{1234.567|number:2}}के रूप में 1,234.57या प्रदान करता है 1 234,57। यदि आप इसे पास करने की कोशिश करते हैं, तो <input type="number" ng-value="1234.567|number:2">आप इनपुट को खाली कर देंगे, क्योंकि मान एक कोर नंबर नहीं है, लेकिन स्थानीय निर्भर स्ट्रिंग प्रतिनिधित्व है।
आदिलक

61

मुझे लगता है कि ऐसा करने का सबसे अच्छा तरीका एक फ़िल्टर बनाना है, जैसे:

myModule.filter('ceil', function() {
    return function(input) {
        return Math.ceil(input);
    };
});

तब मार्कअप इस तरह दिखता है:

<p>The percentage is {{ (100*count/total) | ceil }}%</p>

अपडेटेड फ़िडेल: http://jsfiddle.net/BB4T4/


Klaxon के उत्तर में दिए गए नंबर फ़िल्टर पहले से ही छत को कर देगा, इसलिए उसके लिए कोई ज़रूरत नहीं है।
किम

मैंने ऐसा ही कुछ किया, केवल टाइमर बनाने के लिए फ़िल्टर का उपयोग करके जैसा मैं चाहता था। दूसरे शब्दों में, मैं वर्तमान समय ले लूंगा और इसे एक स्ट्रिंग में प्रारूपित करूंगा क्योंकि मैंने कस्टम फ़िल्टर का उपयोग करके फिट देखा था। इसके अलावा जब आप अपने नंबरों को गोल करना चाहते हैं तो नंबर फिल्टर अच्छा है, लेकिन फर्श और छत के कार्यों के लिए यह बेकार है।
गेब्रियल लवट्रो

37

यह जवाब देने के लिए एक बालों वाला है, क्योंकि आप जो कर रहे हैं उसका पूरा संदर्भ नहीं दिया। स्वीकृत उत्तर काम करेगा, लेकिन कुछ मामलों में खराब प्रदर्शन का कारण होगा। यह, और यह परीक्षण करने के लिए कठिन होने जा रहा है।

यदि आप इसे स्थिर रूप के भाग के रूप में कर रहे हैं, तो ठीक है। स्वीकृत जवाब काम करेगा, भले ही यह परीक्षण करना आसान न हो, और यह हिंकी है।

यदि आप इस बारे में "कोणीय" बनना चाहते हैं:

आप किसी भी "व्यावसायिक तर्क" (यानी तर्क को प्रदर्शित करने के लिए डेटा को बदल देता है) को अपने विचारों से बाहर रखना चाहते हैं। ऐसा इसलिए है कि आप अपने तर्क का परीक्षण कर सकते हैं, और इसलिए आप अपने नियंत्रक और अपने दृष्टिकोण को कसकर युग्मित नहीं करते हैं। सैद्धांतिक रूप से, आपको अपने नियंत्रक को किसी अन्य दृश्य में इंगित करने में सक्षम होना चाहिए और स्कोप से समान मूल्यों का उपयोग करना चाहिए। (यदि इसका कोई औचित्य हो)।

आप यह भी विचार करना चाहेंगे कि किसी भी फ़ंक्शन को एक बंधन के अंदर कॉल किया जाता है (जैसे कि {{}}या ng-bindया ng-bind-html) हर पाचन पर मूल्यांकन करना होगा , क्योंकि कोणीय में यह जानने का कोई तरीका नहीं है कि क्या मूल्य बदल गया है या नहीं जैसा कि यह एक संपत्ति के साथ होगा। दायरे पर।

ऐसा करने का "कोणीय" तरीका यह होगा कि आप किसी प्रॉपर्टी की वैल्यू को किसी चेंज-ऑन इवेंट या किसी $ घड़ी के इस्तेमाल से बदल सकते हैं।

एक स्थिर रूप के साथ उदाहरण के लिए:

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

आप तत्व को संकलित कर सकते हैं और फिर डोम तत्व में पाए गए मूल्य का परीक्षण कर सकते हैं। यह वास्तव में पसंद किया जाता है क्योंकि आप स्थानीयकरण फ़िल्टर का उपयोग कर रहे होंगे।
फ्लेवरस्केप 4

अच्छा उत्तर। लेकिन सोच रहे हैं कि $windowयह सिर्फ योजना के साथ काम करने के लिए क्यों तैयार है Math.round()?
नील

3
@ नील - $ खिड़की आपको Mathपरीक्षणों के लिए अधिक आसानी से नकली करने की अनुमति देती है । अल्टरनेटिवली, आप एक मठ सेवा बना सकते हैं और इसे इंजेक्ट कर सकते हैं।
बेन लेश

8

पूरे गणित को एक छन्नी में क्यों नहीं लपेटते?

var app = angular.module('fMathFilters',[]);


function math() {
    return function(input,arg) {
        if(input) {
            return Math[arg](input);
        }

        return 0;
    }
}

return app.filter('math',[math]);

और उपयोग करने के लिए:

{{नंबर_वर | गणित: 'प्लस्तर लगाना'}}


8

बेहतर विकल्प का उपयोग करना है:

{{(100*score/questionCounter) || 0 | number:0}}

यह मानों में समीकरण के डिफ़ॉल्ट मान को उस स्थिति में सेट करता है जब मान आरंभ नहीं किए जाते हैं।


6

यदि आप कोणीय में एक सरल दौर कर रहे हैं, तो आप आसानी से अपनी अभिव्यक्ति के अंदर फ़िल्टर सेट कर सकते हैं। उदाहरण के लिए:

{{ val | number:0 }}

इस CodePen उदाहरण और अन्य नंबर फ़िल्टर विकल्पों के लिए देखें।

नंबर फिल्टर का उपयोग करने पर कोणीय डॉक्स


6

कोणीय के साथ सरल गणित करने का सबसे आसान तरीका है कि आप अपने पेज पर बड़े पैमाने पर गणना करने की आवश्यकता नहीं है, यह मानते हुए कि सीधे अलग-अलग बाइंडिंग के लिए HTML मार्कअप में है। यहाँ एक उदाहरण है:

{{(data.input/data.input2)| number}} 

इस स्थिति में आप सिर्फ गणित () में करें और फिर एक फ़िल्टर का उपयोग करें एक नंबर का जवाब पाने के लिए। टेक्स्ट के रूप में कोणीय संख्याओं को प्रारूपित करने के बारे में अधिक जानकारी यहां दी गई है:

https://docs.angularjs.org/api/ng/filter


4

या तो वैश्विक गणित की वस्तु को दायरे में बांधें ($ विंडो का उपयोग न करें याद रखें)

$scope.abs = $window.Math.abs;

अपने HTML में बाइंडिंग का उपयोग करें:

<p>Distance from zero: {{abs(distance)}}</p>

या आपके द्वारा किए जाने वाले विशिष्ट मैथ फंक्शन के लिए एक फ़िल्टर बनाएं:

module.filter('abs', ['$window', function($window) {
  return function(n) {
    return $window.Math.abs($window.parseInt(n));
  };
});

अपने HTML में फ़िल्टर का उपयोग करें:

<p>Distance from zero: {{distance | abs}}</p>

2

यह ऐसा करने का एक बहुत कोणीय तरीका नहीं दिखता है। मुझे पूरी तरह से यकीन नहीं है कि यह क्यों काम नहीं करता है, लेकिन आपको इस तरह के फ़ंक्शन का उपयोग करने के लिए गुंजाइश की आवश्यकता होगी।

मेरा सुझाव एक फिल्टर बनाना होगा। वह है कोणीय तरीका।

myModule.filter('ceil', function() {
    return function(input) {
        return Math.ceil(input);
    };
});

फिर अपने HTML में ऐसा करें:

<p>The percentage is {{ (100*count/total) | ceil }}%</p>

1

numberफिल्टर हजारों विभाजक के साथ संख्या स्वरूप है, इसलिए इसे सख्ती से एक गणित समारोह नहीं है।

इसके अलावा, इसके दशमलव 'सीमक' कोई ceilभी कटा हुआ दशमलव नहीं है (जैसा कि कुछ अन्य उत्तर आपको विश्वास करने के लिए प्रेरित करेंगे), बल्कि roundउन्हें निगलना।

तो आप चाहते हैं कि किसी भी गणित समारोह के लिए, आप इसे इंजेक्ट कर सकते हैं (पूरे गणित ऑब्जेक्ट को इंजेक्ट करने की तुलना में आसान करना)

myModule.filter('ceil', function () {
  return Math.ceil;
});

इसे किसी अन्य फ़ंक्शन में भी लपेटने की आवश्यकता नहीं है।


0

यह कमोबेश तीन जवाबों का सारांश है (सारा इनस कैल्डरॉन, क्लेक्सन और गोथबर्ज़ द्वारा), लेकिन जैसा कि वे सभी कुछ महत्वपूर्ण जोड़ते हैं, मैं इसे समाधान में शामिल होने और कुछ और स्पष्टीकरण जोड़ने के लायक मानता हूं।

अपने उदाहरण को ध्यान में रखते हुए, आप अपने टेम्पलेट का उपयोग करके गणना कर सकते हैं:

{{ 100 * (count/total) }}

हालाँकि, इसका परिणाम पूरे दशमलव स्थानों में हो सकता है, इसलिए फ़िल्टर का उपयोग करना एक अच्छा तरीका है:

{{ 100 * (count/total) | number }}

डिफ़ॉल्ट रूप से, संख्या फ़िल्टर तीन भिन्नात्मक अंकों को छोड़ देगा , यह वह जगह है जहां अंशांकन तर्क काफी काम में आता है ( {{ 100 * (count/total) | number:fractionSize }}), जो आपके मामले में होगा:

{{ 100 * (count/total) | number:0 }}

यह पहले से ही परिणाम को गोल करेगा:

अंतिम बात का उल्लेख करें, यदि आप बाहरी डेटा स्रोत पर भरोसा करते हैं, तो संभवत: एक उचित फ़ॉलबैक मूल्य प्रदान करना अच्छा अभ्यास है (अन्यथा आप NaN या अपनी साइट पर कुछ भी नहीं देख सकते हैं):

{{ (100 * (count/total) | number:0) || 0 }}

सिडेनोट: आपके विनिर्देशों के आधार पर, आप अपनी कमियों के साथ और अधिक सटीक होने में सक्षम हो सकते हैं / पहले से ही निचले स्तरों पर कमियां परिभाषित कर सकते हैं (जैसे {{(100 * (count || 10)/ (total || 100) | number:2)}})। हालांकि, यह हमेशा मतलब नहीं हो सकता है ..


0

एक पाइप का उपयोग कर कोणीय टाइपस्क्रिप्ट उदाहरण।

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 घोषणाओं में जोड़ें

@NgModule({
  declarations: [
    MathPipe,

फिर अपने टेम्पलेट में उपयोग करें जैसे:

{{(100*count/total) | math:'round'}}

TypeError: Math [args] एक फंक्शन नहीं है
MattEnth
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.