2016-04-07 14 views
10

Mam nadzieję, że ktoś może mi pomóc! Nakreśliłem dyrektywę owijającą Jasny Bootstrap Plugin bardziej konkretnie o masek wejściowych i wszystko idzie dobrze!Vue js zastosuj filtr na modelu v w polu wejściowym

Teraz zrobiłem niestandardowy filtr obsługiwany przez moment, aby sformatować pole daty!

Format daty, który otrzymuję z aplikacji backendu, to YYY-MM-DD i muszę pokazać w widoku jako DD/MM/YYYY ... Próbowałem już v-model="date | myDate", ale nie działało poprawnie!

JS

Vue.directive('input-mask', { 
    params: ['mask'], 

    bind: function() { 
    $(this.el).inputmask({ 
     mask: this.params.mask 
    }); 

    }, 
}); 

Vue.filter('my-date', function(value, formatString) { 

    if (value != undefined) 
    return ''; 

    if (formatString != undefined) 
    return moment(value).format(formatString); 

    return moment(value).format('DD/MM/YYYY'); 

}); 

var vm = new Vue({ 
    el: 'body', 
    data: { 
    date: '2015-06-26', 
    } 
}); 

HTML

<label>Date</label> 
<input type="text" class="form-control" v-input-mask mask="99/99/9999" v-model="date"> 
<p>{{ date | myDate 'dd/mm/yyyy' }}</p> 

Istnieje JSBin jeśli ktoś jest zainteresowany!

Z góry dziękuję!

EDIT: Wyjaśniając lepiej czego oczekuję =)

Gdy strona najpierw załadować wejście otrzymać wartość 2015-06-26 i chciałbym pokazać, że wartość jako DD/MM/YYYY tak 26.06.2015! Działa poprawnie dopiero po tym, jak zacznę coś pisać!

+0

"To nie działało poprawnie" nie jest wystarczająco opisowe. Wyjaśnij * jak * nie działał poprawnie. Czego się spodziewałeś i co zrobiłeś? –

+0

Sorry @MattJohnson! Właśnie dodałem lepsze wyjaśnienie na dole! Sprawdź, czy rozumiesz, proszę! –

+0

Należy zauważyć, że d/m/yi m/d/r są niejednoznaczne, o wiele lepiej używać nazwy miesiąca takiej jak "10-kwi-2016". – RobG

Odpowiedz

8

Rozumiem, co próbujesz zrobić, jednak ze względu na dwukierunkowość wiązania podczas używania v-modelu, lepiej jest po prostu sformatować datę, gdy otrzymasz je z serwera, a następnie użyć go z żądany format w aplikacji front-end ('DD/MM/YYYY').

Po przesłaniu danych z powrotem do zaplecza, wystarczy sformatować go z powrotem do żądanego formatu serwera ('YYYY-MM-DD').

W swojej aplikacji Vue, przepływ pracy byłoby coś takiego:

new Vue({ 
    el: 'body', 
    data: { 
     date: null, 
    }, 
    methods: { 
     getDataFromServer: function() { 
       //ajaxCall to get data from server 

       //let's pretend the received date data was saved in a variable (serverDate) 
       //let's hardcode for this ex. 
       var serverDate = '2015-06-26'; 

       //format it and save to vue data property 
       this.date = this.frontEndDateFormat(serverDate); 
     }, 
     saveDataToServer: function() { 
      //format data first before sending it back to server 
      var serverDate = this.backEndDateFormat(this.date); 

      //ajax call sending formatted data (serverDate) 
     }, 
     frontEndDateFormat: function(date) { 
      return moment(date, 'YYYY-MM-DD').format('DD/MM/YYYY'); 
     }, 
     backEndDateFormat: function(date) { 
      return moment(date, 'DD/MM/YYYY').format('YYYY-MM-DD'); 
     } 

    } 

    }); 

Działa to dobrze dla mnie, mam nadzieję, że to pomaga.

Oto skrzypce na to:

https://jsfiddle.net/crabbly/xoLwkog9/

+0

OP chce "DD/MM/RRRR", a nie "MM/DD/RRRR" (choć ponieważ oba są niejednoznaczne, użycie nazwy miesiąca lub skrótu będzie bardziej wyraźne). – RobG

+0

@RobG Dziękuję, po prostu edytowałem. Typo tutaj. Moment zaakceptuje jego pożądany format, o ile jest wyraźny. Dyrektywa – crabbly

2

Po uzyskaniu wartości na początku dostosuj ją, aby pasowała do wejścia. Mam to działa w funkcji ready, ale można to zrobić po wywołaniu DB, a także:

ready: function(){  
    var year = this.date.substr(0, 4); 
    var monDay = this.date.substr(5,5); 
    var result = monDay + "-" + year; 
    this.date = result.replace(/-/g,"/"); 
} 

Być może trzeba zrobić coś podobnego w drodze powrotnej do bazy danych, jak również.

6

miałem podobny problem, gdy chciałem na wielkie wartości wejściowej.

To, co skończyło się robi:

// create a directive to transform the model value 
Vue.directive('uppercase', { 
    twoWay: true, // this transformation applies back to the vm 
    bind: function() { 
    this.handler = function() { 
     this.set(this.el.value.toUpperCase()); 
    }.bind(this); 
    this.el.addEventListener('input', this.handler); 
    }, 
    unbind: function() { 
    this.el.removeEventListener('input', this.handler); 
    } 
}); 

Wtedy mogę używać tej dyrektywy na polu wejściowym z v-model.

<input type="text" v-model="someData" v-uppercase="someData"> 

Teraz, gdy wpisuję w tej dziedzinie lub zmienić someData wartość zamienia na wielkie litery.

Zasadniczo zrobiłem to samo, co miałem nadzieję, że zrobi to v-model="someData | uppercase". Ale oczywiście nie możesz tego zrobić.

Podsumowując: należy wprowadzić dyrektywę , która przekształca dane, a nie filtr.

+0

działa po załadowaniu strony lub wpisaniu tekstu przez użytkownika. Gdy interfejs użytkownika zostanie odświeżony z powodu zmiany innych elementów sterujących, metoda aktualizacji dyrektywy nie zostanie wywołana. Wartość w polu tekstowym zostanie przywrócona do niesformatowanej. – flyfrog

+0

@flyfrog Myślę, że lepszym wyborem byłaby własność 'computed' – james2doyle

Powiązane problemy