2016-11-29 11 views
6

Mam następujące pole formularza, które działa poprawnie. Rozumiem przez to, że po wpisaniu, wklejeniu, itp. Do pola, fooObj.expDate zostaje zaktualizowany dokładnie w czasie rzeczywistym i następuje walidacja. Mam pre-tag, żeby to dla mnie było oczywiste.Aktualizowanie pola kątowego 2 programowo

<pre>{{fooObj.someDate | json}}</pre> 

    <div class="form-group inline-form__input"> 
    <label for="someDate">Some Date</label> 
    <input tabindex="2" 
      type="tel" 
      class="form-control" 
      maxlength="7" 
      placeholder="MM/YY" 
      formControlName="someDate" 
      name="someDate" 
      [(ngModel)]="fooObj.someDate" 
      someDate> 
    </div> 

Mam jednak tę dyrektywę someDate w tym polu. Ta dyrektywa przechwytuje zdarzenia wklejania. Anuluje zdarzenie pasty, czy wymyślnej formatowania wejścia, a następnie robi to:

target.value jest mój someDate pola. Wartość zostanie zaktualizowana dobrze wewnątrz pola wprowadzania (widzę, że zmienia się na ekranie wewnątrz wejścia). Jednak fooObj.someDate NIE jest aktualizowany, a sprawdzanie poprawności nie występuje. Na przykład. ustawienie wartości docelowej w limicie czasu NIE wyzwala tej samej aktualizacji/aktualizacji obiektu, jak wpisanie klucza/wklejenia/dowolnego innego zdarzenia javascript.

kątowa docs nie mają wiele do powiedzenia na użyteczne to:

kątowe aktualizuje wiązania (a więc ekran) tylko wtedy, gdy aplikacja robi coś w odpowiedzi na asynchronicznych zdarzeń, takich jak klawiszy. Ten przykładowy kod wiąże zdarzenie keyup z numerem 0, najkrótszym możliwym szablonem. O ile instrukcja nie robi nic użytecznego, to spełnia wymagania Angulara, aby Angular zaktualizował ekran.

Jak zatem uruchomić aktualizację pola z dyrektywy dotyczącej tego pola?

Edit: Próbowałem wyzwolenie zdarzenia na elemencie zgodnie z zaleceniami w komentarzach przy użyciu kodu znajdującego się tutaj na moim elementu: How can I trigger an onchange event manually?

działa dobrze, ale nie wymusza pole do aktualizacji:

if ("createEvent" in document) { 
    var evt = document.createEvent("HTMLEvents"); 
    evt.initEvent("change", false, true); 
    this.target.dispatchEvent(evt); 
    } 
    else 
    this.target.fireEvent("onchange"); 

Również tutaj pojawia się idea syntetycznych zdarzeń, które nie uruchamiają "normalnych" działań jako klucza lub czegoś podobnego (naprawdę mam nadzieję, że błędnie odczytam lub są one błędne w tym przypadku użycia, ale tak się nie stało "). t pracować z próbą ponownego wydania zdarzenia wklejania): https://www.w3.org/TR/clipboard-apis/#clipboard-event-interfaces

UWAGA: Zdarzenia syntetyczne nie mają domyślnych działań. Innymi słowy, podczas gdy powyższy skrypt uruchomi wydarzenie wklejania, dane nie zostaną wklejone do dokumentu.

+0

Czy próbować wywołać 'input' zdarzenie na nim? – Meir

+0

@Meir: Próbowałem ponownie wydać zdarzenie wklejania na nim wcześniej. Powiedziano mi, że to tworzy "syntetyczne" wydarzenie, które nie uruchamia się w taki sam sposób, jak normalne onClick/paste/keyup/cokolwiek. (http://stackoverflow.com/questions/40848003/set-preventdefault-back-to-false-on-javascript-event). Mam zamiar spróbować onChange() i po prostu wydawanie zwykłego zdarzenia KeyUp. – VSO

+0

spróbuj także "input" event – Meir

Odpowiedz

2

Nie znam szczegółów twojej dyrektywy, ale mogę zgadnąć, co do twoich intencji. Na początek, mamy zamiar zapisać się do valueChanges obserwowalne naszą kontrolą i unikać dwie sposób wiążący się bezpośrednio na kontrolę tylko w celu uniknięcia nadmiernych pisze i kontrole:

form.html

<input tabindex="2" 
      type="tel" 
      class="form-control" 
      maxlength="7" 
      placeholder="MM/YY" 
      formControlName="someDate" 
      name="someDate" 
      someDate /> 

form.ts

Oto, gdzie subskrybujemy (może wyjść z konstruktora, zależy od tego, kiedy tworzysz formularz).

constructor() { 
    this.myForm = new FormGroup({ 
     someDate: new FormControl(''), 
    }); 

    this.myForm.controls['someDate'].valueChanges.subscribe(
     value => this.fooObj.someDate = value; 
    ); 
    } 

pewne-date.directive.ts

Dyrektywa napiszę wartość do kontroli i prenumeratę valueChanges następnie zaktualizować nasz model. Działa to w przypadku wklejenia i każdego innego zdarzenia (dzięki czemu można ograniczyć docelowe zdarzenia, ale chciałem przynajmniej upewnić się, że wklejanie zadziałało).

@Directive({ 
    selector: '[someDate]' 
}) 
export class SomeDateDirective{ 
    constructor(private el: ElementRef, private control : NgControl) { 

    } 

    @HostListener('input',['$event']) onEvent($event){ 
    $event.preventDefault(); 
    let data = $event.clipboardData.getData('text'); 
    setTimeout(() => { 
     this.control.control.setValue(data.toUpperCase()); 
    }, 3000); 
    } 
} 

Zmiana paste zamiast input uchwycić tylko onpaste wydarzenia. To trochę dziwne z preventDefault(), ponieważ dane wejściowe skutecznie znikają na jakiś czas.

Oto plunker: http://plnkr.co/edit/hsisILvtKErBBOXECt8t?p=preview

+0

WHOO! Dokładnie tego potrzebuję. Nie zaimplementowałem go, ale na pewno zadziała. Ty bardzo za pluna. – VSO

+1

@VSO Cieszę się, że mogłem pomóc. – silentsod

Powiązane problemy