2016-04-07 13 views
10

Hoffe jemand kann mir helfen! Ich habe eine Direktive gemacht, die das Jasny Bootstrap Plugin genauer beschreibt als die Eingabemaske und alles geht gut!Vue js Filter auf V-Modell in einem Eingabefeld anwenden

Jetzt habe ich einen benutzerdefinierten Filter unterstützt von Moment, um das Datumsfeld zu formatieren!

Das Datumsformat, das ich von meiner Backend-Anwendung erhalte, ist YYY-MM-DD und ich muss in der Ansicht als DD/MM/YYYY anzeigen ... Ich habe versucht v-model="date | myDate" aber es hat nicht richtig funktioniert!

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> 

Es ist die JSBin, wenn jemand interessiert!

Vielen Dank im Voraus!

EDIT: Erklären besser, was ich = erwarten)

Wenn die Seite zuerst die Eingänge laden erhält den Wert von 2015.06.26 und ich würde diesen Wert als DD/MM/YYYY zeigen, wie so 26/06/2015! Es funktioniert nur, nachdem ich etwas zu tippen begonnen habe!

+0

"Es hat nicht richtig funktioniert" ist nicht beschreibend genug. Bitte erklären * wie * es nicht richtig funktioniert. Was haben Sie erwartet und was hat es getan? –

+0

Sorry @MattJohnson! Habe einfach eine bessere Erklärung auf der Unterseite hinzugefügt! Sehen Sie, wenn Sie verstehen, bitte! –

+0

Beachten Sie, dass d/m/y und m/d/y mehrdeutig sind, viel besser, den Monatsnamen wie '10-Apr-2016' zu verwenden. – RobG

Antwort

8

Ich verstehe, was Sie versuchen, jedoch wegen der Zwei-Wege-Bindung bei der Verwendung von V-Modell, kann es besser sein, nur das Datum zu formatieren, wie Sie es vom Server erhalten, und verwenden Sie es dann mit das gewünschte Format in Ihrer Front-End-App ('DD/MM/YYYY').

Wenn Sie die Daten zurück an das Back-End senden, formatieren Sie sie einfach zurück in das gewünschte Serverformat ('YYYY-MM-DD').

In Ihrer Vue App würde der Arbeitsablauf so etwas wie dieses:

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

    } 

    }); 

Dies funktioniert gut für mich, hoffe, es hilft.

Hier ist eine Geige für sie:

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

+0

Das OP will "DD/MM/YYYY", nicht "MM/DD/YYYY" (obwohl beide mehrdeutig sind, wäre die Verwendung des Monats Name oder Abkürzung klarer). – RobG

+0

@RobG Danke, gerade editiert. Tippfehler hier. Moment akzeptiert sein gewünschtes Format, solange es explizit ist. – crabbly

2

Wenn Sie den Wert anfänglich erhalten, passen Sie ihn an die Eingabe an. Ich habe es in der ready Funktion arbeiten, aber man kann dies nach dem DB-Aufruf auch tun:

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,"/"); 
} 

Sie haben auch bis zu Ihrer Datenbank etwas ähnliches auf dem Weg zurück zu tun.

6

Ich hatte ein ähnliches Problem, wenn ich einen Eingabewert in Großbuchstaben gesucht.

Dies ist, was ich tun endete:

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

Dann kann ich mit einem v-model diese Richtlinie über das Eingabefeld verwenden.

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

Nun, wenn ich in dieses Feld eingeben oder someData ändern, wird der Wert in Großbuchstaben umgewandelt.

Dies tat im Wesentlichen das gleiche, was ich gehofft hatte v-model="someData | uppercase" würde tun. Aber natürlich können Sie das nicht tun.

In summary: eine Direktive machen, die die Daten transformiert, kein Filter.

+0

Direktive funktioniert, wenn die Seite geladen wird oder der Benutzer Text eingibt. Wenn die Benutzeroberfläche aufgrund von Änderungen in anderen Steuerelementen aktualisiert wird, wird die update-Methode für die Direktive nicht aufgerufen. Der Wert in der Textbox wird in den unformatierten Wert zurückgesetzt. – flyfrog

+0

@flyfrog Ich denke, eine bessere Wahl wäre hier eine "berechnete" Eigenschaft – james2doyle