NgModel içindeki Boruları Açısal INPUT Öğelerinde Kullanma


144

Bir HTML INPUT alanım var.

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

ve değerini biçimlendirmek ve mevcut bir boruyu kullanmak istiyorum:

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

ve hata mesajını alın:

Eylem ifadesinde kanal olamaz

Boruları bu bağlamda nasıl kullanabilirim?

Yanıtlar:


215

Şablon ifadesinde Şablon ifadesi işleçlerini (dikey çizgi, gezgini kaydet) kullanamazsınız :

(ngModelChange)="Template statements"

(ngModelChange) = "item.value | useMyPipeToFormatThatValue = $ olay"

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

Şablon ifadeleri gibi, şablon ifadeleri de JavaScript'e benzeyen bir dil kullanır. Şablon deyimi ayrıştırıcısı, şablon ifadesi ayrıştırıcısından farklıdır ve özellikle hem temel atamayı (=) hem de zincirleme ifadelerini (veya;) ile destekler.

Ancak, belirli JavaScript sözdizimine izin verilmez :

  • yeni
  • arttırma ve azaltma operatörleri, ++ ve -
  • operatör ataması, örneğin + = ve - =
  • yönlü operatörler | ve &
  • şablon ifade operatörleri

Bu yüzden aşağıdaki gibi yazmalısınız:

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

Plunker Örneği


3
Birisi neden bu şekilde bölünmesi gerektiğini açıklayabilir mi? Bir tarih türü girişiyle bir tarih bağlamak için çalışıyorum: [(ngModel)] = "model.endDate | date: 'y-MM-dd'" ve boru çalışmaz. Ancak, ben muz sözdizimi ile ortadan kaldırmak ve yukarıdaki bölünmüş sözdizimi kullanırsanız iyi çalışır.
Blake Rivell

Bu gerçekten işe yaradı mı? benim için işe yaramadı. bir eylem ifadesinde pipo yapılamıyor diyor
NoStressDeveloper

4
Bu benim için çalıştı! @BlakeRivell "[]" özelliği veri kaynağından tek yönlü olarak bağlayarak hedefi görüntüleyebilir. Bu noktada bir kanalla görüntülenme şeklini değiştirebilirsiniz. "()" Bağını kullanırken, formatı değiştirmenin başka bir yolu da burada işe yaramaz. Bu yüzden sanırım muz neden bir kutu içinde "[()]" bir boru ile çalışmaz ve onları bölmek yoludur. Bununla ilgili daha fazla bilgiyi buradan edinebilirsiniz: angular.io/docs/ts/latest/guide/…
Mike Bovenlander

8
Örnekte borunun sadece bir yönde çalıştığına dikkat edin. Diyelim ki item.valuebir sayı ve bunu DatePipebir tarih dizesine dönüştürmek için kullanıyorsunuz . Tarih düzenlendiğinde, $eventaynı zamanda bir tarih dizesi olacaktır ve geri sığmayacaksınız item.valueİfadenizde borunun yaptıklarını tersine (ngModelChange)çevirmelisiniz - yani tarih dizesini bir sayıya geri çevirin.
Tuupertunut

3
@Protagonist (ngModelChange)="updateItemValue($event)", sonra bir updateItemValue(date: string)yöntem oluşturun ve içinde item.value = someConversionFunction(date); Şimdi dönüştürme işlevi olarak ne kullanmanız gerektiğini soruyorsanız, bilmiyorum. Belki Date.parse()işe yarayabilir.
Tuupertunut

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

Buradaki çözüm, sözdiziminin [(ngModel)]gerçekte kapsadığı tek yönlü bir bağlamaya ve bir olay bağlamasına bölünmektir . []tek yönlü bağlayıcı sözdizimidir ve ()olay bağlayıcı sözdizimidir. Birlikte kullanıldığında - [()]Angular bunu steno olarak tanır ve iki yönlü bir bağlamayı tek yönlü bir bağlanma ve bir bileşen nesne değerine bağlanan bir olay şeklinde bağlar.

[()]Bir boru ile kullanamamanızın nedeni , boruların sadece tek yönlü bağlantılarla çalışmasıdır. Bu nedenle boruyu sadece tek yönlü ciltleme üzerinde çalışacak şekilde ayırmanız ve olayı ayrı olarak ele almanız gerekir.

Daha fazla bilgi için Açısal Şablon Sözdizimi konusuna bakın .


1
| Gibi koşul ifadesini nasıl eklerim? sayı: '3.2-5'?
Kahraman

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

Kabul edilen cevaba bir puan daha eklemek istiyorum.

Giriş kontrolünüzün tipi metin değilse, boru çalışmaz.

Unutmayın ve zaman kazanın.


lütfen cevabınıza daha fazla bilgi eklemeyi düşünün
Inder

1
belirli bir para birimi için giriş kutusuna maskelemek için yaptığım ngx-locale-mask açısal kütüphaneyi kontrol edin
Tibin Thomas

6

Yukarıdaki çözümleri denedim, ancak modele giden değer, döndürülen ve bana currencyPipe hataları veren biçimlendirilmiş değerdi. Bu yüzden yapmak zorundaydım

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

Ve addToAmount -> bulanıklık üzerinde değişiklik fonksiyonu üzerinde ngModelChange bana imleç sorunları veriyor neden oldu.

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

Ve diğer sayısal olmayan değerleri kaldırmak.

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

Yüzde borusu için seçilen cevabı da denedik ve (ngModelChange) için toDecimal () gibi bir yöntem yazdık ve 2 yöntem birbirini takip ediyor. böylece 1 basamaktan fazlasını yazamazsınız. çok beğenildi şaşırtıcı
Angela P

1

Benim Çözüm aşağıda verilen searchDetail bir nesnedir ..

<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)] ile iki yönlü model bağlama yerine [ngModel] kullanmalısınız. ardından (ngModelChange) ile manuel değiştirme olayını kullanın. bu, bileşenlere iki yönlü girişlerin tümü için genel kuraldır.

çünkü olay vericideki boru yanlış.


0

çünkü iki yönlü ciltleme, önlemek için hata:

ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was 
checked.

modeli aşağıdaki gibi değiştirmek için bir işlev çağırabilirsiniz:

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

bu hatayı önlemek için daha iyi bir çözüm varsa iyi olur.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.