2016-04-07 3 views
10

Надеюсь, кто-то может мне помочь! Я сделал директиву, вставляя плагин Jasny Bootstrap более конкретно в маска ввода-маски, и все идет хорошо!Vue js применить фильтр на v-модели в поле ввода

Теперь я создал настраиваемый фильтр, поддерживаемый моментом для форматирования поля даты!

Формат даты, который я получаю от моего backend-приложения, - это YYY-MM-DD, и я должен показать его в виде DD/MM/YYYY ... Я пробовал v-model="date | myDate", но это не сработало!

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> 

Существует JSBin, если кто-то заинтересован!

Заранее благодарен!

EDIT: Объясняя лучше, что я жду =)

Когда страница первой загрузки вход получить значение 2015-06-26, и я хотел бы показать, что значение как DD/MM/YYYY так 26/06/2015! Он работает правильно только после того, как я начинаю набирать что-то!

+0

«это не сработало правильно» недостаточно описательно. Пожалуйста, объясните *, как это работает неправильно. Что вы ожидали, и что он сделал вместо этого? –

+0

Извините @MattJohnson! Просто добавлено лучшее объяснение внизу! Смотрите, понимаете ли вы, пожалуйста! –

+0

Обратите внимание, что d/m/y и m/d/y являются двусмысленными, гораздо лучше использовать название месяца, например '10-Apr-2016'. – RobG

ответ

8

Я понимаю, что вы пытаетесь сделать, однако, из-за двухсторонней привязки при использовании v-модели, может быть, лучше просто форматировать дату, когда вы ее получите с сервера, а затем использовать ее с помощью нужный формат в вашем внешнем приложении ('DD/MM/YYYY').

При отправке данных обратно на задний план вы просто отформатируете его обратно в желаемый формат сервера ('YYYY-MM-DD').

В вашем Вьет приложение, работа поток будет что-то вроде этого:

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

    } 

    }); 

Это хорошо работает для меня, надеюсь, что это помогает.

Вот скрипку для него:

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

+0

OP хочет «DD/MM/YYYY», а не «MM/DD/YYYY» (хотя, поскольку оба значения неоднозначны, использование имени месяца или аббревиатуры будет более четким). – RobG

+0

@RobG Спасибо, только что отредактировал его. Остановитесь здесь. Moment будет принимать желаемый формат, если он явно. Директива – crabbly

2

Когда вы сначала получаете значение, отрегулируйте его, чтобы он соответствовал входу. Я получил это работает в функции ready, но вы могли бы сделать это после DB вызова, а также:

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

Вы, возможно, придется сделать что-то подобное на обратном пути к вашей базе данных.

6

У меня была аналогичная проблема, когда я хотел прописные значение входного сигнала.

Это то, что я в конечном итоге делает:

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

Тогда я могу использовать эту директиву на поле ввода с v-model.

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

Теперь, когда я набираю в это поле или изменить someData, значение преобразуется в верхний регистр.

Это по существу то же самое, что я надеялся, что v-model="someData | uppercase" будет делать. Но, конечно, вы не можете этого сделать.

В суммировании: введите директива, которая преобразует данные, а не фильтр.

+0

работает, когда страница загружена или пользовательские типы в тексте. Когда пользовательский интерфейс обновляется из-за изменения других элементов управления, метод обновления по директиве не будет вызываться. Значение в текстовом поле будет возвращено к неформатированному. – flyfrog

+0

@flyfrog Я думаю, что лучшим выбором здесь будет свойство 'computed' – james2doyle