कोणीय में INPUT तत्वों पर ngModel के भीतर पाइप का उपयोग करना


144

मेरे पास एक HTML INPUT फ़ील्ड है।

<input 
    [(ngModel)]="item.value" 
    name="inputField" 
    type="text" 
/>

और मैं इसके मूल्य को प्रारूपित करना चाहता हूं और मौजूदा पाइप का उपयोग करना चाहता हूं:

.... 
[(ngModel)]="item.value | useMyPipeToFormatThatValue" 
....

और त्रुटि संदेश प्राप्त करें:

एक्शन एक्सप्रेशन में पाइप नहीं हो सकता

मैं इस संदर्भ में पाइप का उपयोग कैसे कर सकता हूं?

जवाबों:


214

आप टेम्प्लेट स्टेटमेंट में टेम्प्लेट एक्सप्रेशन ऑपरेटर (पाइप, नाविक सेव) का उपयोग नहीं कर सकते हैं :

(ngModelChange)="Template statements"

(ngModelChange) = "item.value | यूपाइपमाइपटाइपफोर्मैटट व्हाटवेलू = अन्य ईवेंट"

https://angular.io/guide/template-syntax#template-statements

टेम्प्लेट अभिव्यक्तियों की तरह, टेम्प्लेट स्टेटमेंट एक भाषा का उपयोग करते हैं जो जावास्क्रिप्ट की तरह दिखाई देती है। टेम्प्लेट स्टेटमेंट पार्सर टेम्प्लेट एक्सप्रेशन पार्सर से भिन्न होता है और विशेष रूप से दोनों बेसिक असाइनमेंट (=) और चेनिंग एक्सप्रेशन (साथ; या;) दोनों को सपोर्ट करता है।

हालाँकि, कुछ जावास्क्रिप्ट सिंटैक्स की अनुमति नहीं है :

  • नया
  • वेतन वृद्धि और वेतन वृद्धि ऑपरेटरों, ++ और -
  • ऑपरेटर असाइनमेंट, जैसे कि + = और - =
  • बिटवाइज ऑपरेटर्स | तथा &
  • टेम्पलेट अभिव्यक्ति ऑपरेटरों

इसलिए आपको इसे इस प्रकार लिखना चाहिए:

<input [ngModel]="item.value | useMyPipeToFormatThatValue" 
      (ngModelChange)="item.value=$event" name="inputField" type="text" />

प्लंकर उदाहरण


3
क्या कोई समझा सकता है कि इसे इस तरह विभाजित क्यों किया जाना चाहिए? मैं एक तिथि को टाइप तिथि के साथ एक इनपुट में बाँधने की कोशिश कर रहा हूँ: [(ngModel)] = "model.endDate | तिथि: 'y-MM-dd'" और पाइप काम नहीं करेगा। हालांकि, अगर मैं केले के सिंटैक्स के साथ दूर करता हूं और ऊपर का सिंटैक्स का उपयोग करता है तो यह ठीक काम करता है।
ब्लेक रिवल

क्या यह वास्तव में काम करता है? यह मेरे लिए काम नहीं किया। यह कहता है कि एक्शन एक्सप्रेशन में एक पाइप नहीं हो सकता है
NoStressDeveloper

4
यह मेरे लिए काम किया! @BlakeRivell "[]" प्रॉपर्टी को डेटा स्रोत से उस दिशा में लक्ष्य को देखने के लिए एक तरह से बांधता है आप इसे बदल सकते हैं कि यह एक पाइप के साथ कैसे प्रदर्शित होता है। जब "" () "बाइंडिंग" का उपयोग किया जाता है, तो यह प्रारूप बदलने के इर्द-गिर्द एक और तरीका है, यहाँ बेकार होगा। इसलिए मुझे लगता है कि एक बॉक्स में केला क्यों है [[(]] "एक पाइप के साथ काम न करें और उन्हें विभाजित करने का तरीका है। आप इसके बारे में और अधिक यहाँ पढ़ सकते हैं: angular.io/docs/ts/latest/guide/…
माइक बुवेनलैंडर

8
खबरदार कि उदाहरण में पाइप केवल एक दिशा में काम करता है। मान लीजिए कि item.valueयह एक संख्या है, और आप DatePipeइसे एक तारीख स्ट्रिंग में बदलने के लिए उपयोग करते हैं। जब तारीख को संपादित किया जाता है, तो $eventवसीयत भी एक तारीख स्ट्रिंग होगी और वापस में फिट नहीं होगी। item.valueआपको अपनी (ngModelChange)अभिव्यक्ति में पाइप ने जो किया है उसे उल्टा करना होगा - यानी तारीख स्ट्रिंग को एक संख्या में वापस करें।
तुपरटुनट

3
@ विरोधी (ngModelChange)="updateItemValue($event)", फिर एक updateItemValue(date: string)विधि बनाएं और उसके अंदर item.value = someConversionFunction(date); अब यदि आप पूछ रहे हैं कि आपको रूपांतरण फ़ंक्शन के रूप में क्या उपयोग करना चाहिए, तो मुझे नहीं पता। शायद Date.parse()काम आ जाए।
तुपुर्तनुत

111
<input [ngModel]="item.value | useMyPipeToFormatThatValue" 
      (ngModelChange)="item.value=$event" name="inputField" type="text" />

इसका समाधान यह है कि बाइंडिंग को एक-तरफ़ा बाइंडिंग और एक ईवेंट बाइंडिंग में विभाजित किया जाए - जो कि सिंटैक्स [(ngModel)]वास्तव में शामिल है। []एक तरह से बाइंडिंग सिंटैक्स है और ()ईवेंट बाइंडिंग सिंटैक्स है। जब एक साथ उपयोग किया जाता है - [()]कोणीय इसे शॉर्टहैंड के रूप में पहचानता है और एक-तरफ़ा बंधन के रूप में दो-तरफ़ा बंधन और एक घटक वस्तु मान के लिए एक घटना बाध्यकारी होता है।

जिस कारण से आप [()]पाइप का उपयोग नहीं कर सकते, वह यह है कि पाइप केवल एकतरफा बाइंडिंग के साथ काम करते हैं। इसलिए आपको केवल एक-तरफ़ा बाइंडिंग पर काम करने के लिए पाइप को अलग करना होगा और अलग से घटना को संभालना होगा।

अधिक जानकारी के लिए कोणीय टेम्पलेट सिंटैक्स देखें ।


1
मैं कैसे हालत की अभिव्यक्ति जोड़ सकता हूँ | संख्या: '3.2-5'?
नायक

14
<input [ngModel]="item.value | currency" (ngModelChange)="item.value=$event"
name="name" type="text" />

मैं स्वीकृत उत्तर में एक और बिंदु जोड़ना चाहूंगा।

यदि आपके इनपुट नियंत्रण का प्रकार टेक्स्ट नहीं है तो पाइप काम नहीं करेगा।

इसे ध्यान में रखें और अपना समय बचाएं।


कृपया अपने उत्तर में अधिक जानकारी जोड़ने पर विचार करें
Inder

1
एनएक्सएक्स-लोकेल-मास्क एंगुलर लाइब्रेरी की जांच करें जो मैंने कोणीय लोकेल पर आधारित एक विशेष मुद्रा के लिए इनपुट बॉक्स को मुखौटा बनाया था
टिबिन थॉमस सेप

6

मैंने ऊपर दिए गए समाधानों की कोशिश की, फिर भी जो मूल्य मॉडल पर जाता है वह स्वरूपित मूल्य था फिर लौटकर मुझे करेंसीपाइप त्रुटियां देता है। इसलिए मुझे करना पड़ा

  [ngModel]="transfer.amount | currency:'USD':true"
                                   (blur)="addToAmount($event.target.value)"
                                   (keypress)="validateOnlyNumbers($event)"

और addToAmount के फ़ंक्शन पर -> ब्लर कारण पर परिवर्तन ngModelChange मुझे कर्सर समस्या दे रहा था।

removeCurrencyPipeFormat(formatedNumber){
    return formatedNumber.replace(/[$,]/g,"")
  }

और अन्य गैर-संख्यात्मक मानों को हटा रहा है।

validateOnlyNumbers(evt) {
  var theEvent = evt || window.event;
  var key = theEvent.keyCode || theEvent.which;
  key = String.fromCharCode( key );
  var regex = /[0-9]|\./;
  if( !regex.test(key) ) {
    theEvent.returnValue = false;
    if(theEvent.preventDefault) theEvent.preventDefault();
  }

हमने पेरेंट पाइप के लिए चुने गए उत्तर को भी आज़माया और (ngModelChange) के लिए toDecimal () जैसी विधि लिखी, और 2 विधियाँ एक दूसरे का पीछा करती हैं। इसलिए आप 1 अंक से अधिक नहीं टाइप कर सकते हैं। आश्चर्य की बात है कि यह बहुत ऊपर चढ़ा हुआ है
एंजेला पी

1

मेरा समाधान नीचे दिया गया है यहां searchDetail एक ऑब्जेक्ट है ..

<p-calendar  [ngModel]="searchDetail.queryDate | date:'MM/dd/yyyy'"  (ngModelChange)="searchDetail.queryDate=$event" [showIcon]="true" required name="queryDate" placeholder="Enter the Query Date"></p-calendar>

<input id="float-input" type="text" size="30" pInputText [ngModel]="searchDetail.systems | json"  (ngModelChange)="searchDetail.systems=$event" required='true' name="systems"
            placeholder="Enter the Systems">

0

[[ngModel]] के साथ बाइंडिंग मॉडल के बजाय आपको [ngModel] का उपयोग करना चाहिए। फिर (ngModelChange) के साथ मैन्युअल परिवर्तन घटना का उपयोग करें। यह घटकों में सभी दो तरह के इनपुट के लिए सार्वजनिक नियम है।

क्योंकि इवेंट एमिटर पर पाइप गलत है।


0

दो तरह से बाध्यकारी होने के कारण, की त्रुटि को रोकने के लिए:

ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was 
checked.

आप इस तरह से मॉडल बदलने के लिए एक फ़ंक्शन को कॉल कर सकते हैं:

<input [ngModel]="item.value" 
  (ngModelChange)="getNewValue($event)" name="inputField" type="text" />


import { UseMyPipeToFormatThatValuePipe } from './path';

constructor({
    private UseMyPipeToFormatThatValue: UseMyPipeToFormatThatValuePipe,
})

getNewValue(ev: any): any {
    item.value= this.useMyPipeToFormatThatValue.transform(ev);
}

यह अच्छा होगा यदि इस त्रुटि को रोकने के लिए एक बेहतर समाधान है।

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