Ng modeli kullanarak bir tarih nasıl biçimlendirilir?


94

Olarak tanımlanmış bir girdim var

<input class="datepicker" type="text" ng-model="clientForm.birthDate" />

Sayfanın başka bir yerinde görüntülenecek şekilde düzenlenmiş:

<tr>
    <th>Birth Date</th>
    <td>{{client.birthDate|date:'mediumDate'}}</td>
</tr>

Sayfa yüklendiğinde, doğum tarihi güzel bir şekilde biçimlendirilir Dec 22, 2009. Yaşıyorum benim içine bakmak Ancak, <input>o kadar gösterilene Tue Dec 22 2009 00:00:00 GMT-0800 (Pacific Standard Time)hangi sanırım JS nasıl oluşturduğunu olduğu Datedizeleri olarak nesneleri.

İlk olarak, Angular'a tarihin içindeki <input>gibi bir şey göstermesini nasıl söylerim 12/22/2009? Özelliğin |filtersiçine uygulayamıyorum ng-model.

İkinci olarak, tarihi düzenler değiştirmez, orijinal biçiminde tutsam bile, diğer metnim (içindeki <td>) |dateartık filtreyi uygulamıyor gibi görünüyor ; biçimleri giriş metin kutusununkiyle eşleşecek şekilde aniden değiştirir. |dateModel her değiştiğinde filtreyi nasıl uygulayabilirim ?


İlgili sorular:


Bu konuda da bir sorun yaşadım, ancak standart js Date()işlevlerini kullanarak daha basit bir çözümle geldim : $scope.departDate = new Date(); $scope.departTime = $scope.departDate.toTimeString().slice(0, 5);Ve diğer filtrelere veya AngularJS IMO'da zor geçici çözümlere gerek yok.
boldnik

Yanıtlar:


71

Formların özel doğrulamasını kullanın http://docs.angularjs.org/guide/forms Demo: http://plnkr.co/edit/NzeauIDVHlgeb6qF75hX?p=preview

Biçimlendiriciler ve ayrıştırıcılar ve MomentJS kullanan yönerge )

angModule.directive('moDateInput', function ($window) {
    return {
        require:'^ngModel',
        restrict:'A',
        link:function (scope, elm, attrs, ctrl) {
            var moment = $window.moment;
            var dateFormat = attrs.moDateInput;
            attrs.$observe('moDateInput', function (newValue) {
                if (dateFormat == newValue || !ctrl.$modelValue) return;
                dateFormat = newValue;
                ctrl.$modelValue = new Date(ctrl.$setViewValue);
            });

            ctrl.$formatters.unshift(function (modelValue) {
                if (!dateFormat || !modelValue) return "";
                var retVal = moment(modelValue).format(dateFormat);
                return retVal;
            });

            ctrl.$parsers.unshift(function (viewValue) {
                var date = moment(viewValue, dateFormat);
                return (date && date.isValid() && date.year() > 1950 ) ? date.toDate() : "";
            });
        }
    };
});

4
Küçük bir biçimlendirici ve ayrıştırıcı örneği oluşturmak istedim, Bugünkü sorunuz sayesinde bunu yapmak için bir nedenim var.
SunnyShah

1
@Mark, İkinci kemanta Nan sorunu düzeltildi. ;)
SunnyShah

1
İkinci yaklaşım kaldırıldı. Çok hatalıydı.
SunnyShah

1
Daha fazla iyileştirme yapmak için değişim direktifini kullanabilirsiniz. stackoverflow.com/questions/14477904/…
SunnyShah

7
@SunnyShah - harika şeyler, gerçekten faydalı, çok teşekkürler. Neden moMediumDate'e sahip var dateFormat = attrs.moMediumDate;olup olmadığınızı merak ediyordum, bu nedenle var dateFormat = attrs.moDateInput;girdiler dinamik olarak oluşturulmazsa, bir başlangıç ​​biçimi asla seçilmez.
toxaq

37

İşte çok kullanışlı açısal-tarih-saat yönergesi . Bunu şu şekilde kullanabilirsiniz:

<input type="text" datetime="yyyy-MM-dd HH:mm:ss" ng-model="myDate">

Ayrıca girişinize maske ekler ve doğrulama gerçekleştirir.


1
Ben de bu yönergeyi kullandım, teşekkürler. Bunu jQuery UI Datepicker ile kullanıyorsanız, datetime="<format>"öznitelik değerinde belirtilen formatın Datepicker dateFormatseçeneğinde belirtilen formatla eşleştiğinden emin olmalısınız .
tylerwal

1
Sadece birkaç artı oyla burada mükemmel bir çözümün nasıl mümkün olduğunu merak ediyorum. Tarihler için çok fazla ve bunları hemen burada, hemen şimdi çözebilirsiniz! Tesekkurler dostum.
C0ZEN

2
Mevcut bir açısal uygulamaya dahil etmeyi kolaylaştırmak için dokümantasyon iyileştirilirse, eminim daha fazla insan buna oy verirdi.
Joel Hansen

8

Standart input[type="date"]form öğelerinin AngularJS ~ 1.2.16 ile düzgün çalışmasını sağlamak için basit bir yönerge oluşturdum .

Buraya bakın: https://github.com/betsol/angular-input-date

Ve işte demo: http://jsfiddle.net/F2LcY/1/


Hey @Lorenzo, ne demek istiyorsun? Lütfen detaylandırır mısınız?
Slava Fomin II

Ayın yılın günü, Pzt Sal, Wen
Merlin

@Lorenzo Anladığımdan emin değilim. Direktifin yerelleştirme ile ilgisi yoktur. Muhtemelen kullandığınız biçimlendirme işlevi, tarayıcınızdan / sisteminizden yerel ayarı alıyor. Bir örnek verirseniz size yardımcı olabilirim (jsfiddle).
Slava Fomin II

1
sadece kromu destekleyin, çok kötü.
İkizler Sarı

Direktifin amacı tüm platformları desteklemektir. Bununla ilgili sorunlarınız varsa neden GitHub deposunda bir sorun oluşturmuyorsunuz? Her zaman tüm konulara cevap veriyorum.
Slava Fomin II

7

Tarih seçmek için jquery datepicker kullanıyorum. ng-modelYönergem tarihi okudu ve onu json tarih biçimine (milisaniye cinsinden) dönüştürürken, biçimlendirilmiş tarihi görüntülerken verileri depolar. Ve ng-modelinde json tarihi varsa (milisaniye cinsinden) biçimlendiricim jquery veri seçici olarak biçimimde görüntülenir.

HTML Kodu:

<input type="text" jqdatepicker  ng-model="course.launchDate" required readonly />

Açısal Yönerge:

myModule.directive('jqdatepicker', function ($filter) {
    return {
        restrict: 'A',
        require: 'ngModel',
         link: function (scope, element, attrs, ngModelCtrl) {
            element.datepicker({
                dateFormat: 'dd/mm/yy',
                onSelect: function (date) {   
                    var ar=date.split("/");
                    date=new Date(ar[2]+"-"+ar[1]+"-"+ar[0]);
                    ngModelCtrl.$setViewValue(date.getTime());            
                    scope.$apply();
                }
            });
            ngModelCtrl.$formatters.unshift(function(v) {
            return $filter('date')(v,'dd/MM/yyyy'); 
            });

        }
    };
});

Aman Tanrım!! Çok teşekkür ederim sooooo !! Kelimenin tam anlamıyla iki gündür bu gibi bir cevap aradım, ama bulamadım! Harikasın!
Michael Rentmeister

Fantastik. Bir süredir böyle bir şey arıyordum. Çözümüm için materializecss kullanıyorum. Bu ve ihtiyaca göre birisi stubles Materialise için bu yönergeyi dönüştürmek için, sadece takas element.datepickerileelement.pickadate
IWI

7

Sınıf olarak datepicker'ı kullandığınızdan beri, bir Jquery datepicker veya benzeri bir şey kullandığınızı varsayıyorum.

Moment.js kullanmadan, sadece datepicker ve angularjs direktiflerini kullanarak amaçladığınız şeyi yapmanın bir yolu var.

Bu Fiddle'da bir örnek verdim

Kemancadan alıntılar burada:

  1. Datepicker'ın farklı bir formatı vardır ve angularjs formatı farklıdır, uygun eşleşmeyi bulması gerekir, böylece kontrolde tarih önceden seçilir ve ayrıca ng modeli bağlıyken giriş alanına da doldurulur. Aşağıdaki biçim, 'mediumDate'AngularJS biçimine eşdeğerdir .

    $(element).find(".datepicker")
              .datepicker({
                 dateFormat: 'M d, yy'
              }); 
    
  2. Tarih girdisi yönergesinin, tarihin insan tarafından okunabilir biçimini temsil etmesi için bir ara dizge değişkenine sahip olması gerekir.

  3. Sayfanın farklı bölümlerinde yenileme, $broadcastve gibi etkinlikler aracılığıyla gerçekleşmelidir $on.

  4. Tarihi insan tarafından okunabilir biçimde göstermek için filtre kullanmak, ng modelinde de mümkündür, ancak geçici bir model değişkeni ile.

    $scope.dateValString = $filter('date')($scope.dateVal, 'mediumDate');
    

6

Beni ve çoğu kullanıcıyı çok mutlu eden aşağıdaki yönergeyi kullanıyorum! Ayrıştırma ve biçimlendirme için moment kullanır. Daha önce bahsedilen SunnyShah'ınkine biraz benziyor.

angular.module('app.directives')

.directive('appDatetime', function ($window) {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function (scope, element, attrs, ngModel) {
            var moment = $window.moment;

            ngModel.$formatters.push(formatter);
            ngModel.$parsers.push(parser);

            element.on('change', function (e) {
                var element = e.target;
                element.value = formatter(ngModel.$modelValue);
            });

            function parser(value) {
                var m = moment(value);
                var valid = m.isValid();
                ngModel.$setValidity('datetime', valid);
                if (valid) return m.valueOf();
                else return value;
            }

            function formatter(value) {
                var m = moment(value);
                var valid = m.isValid();
                if (valid) return m.format("LLLL");
                else return value;

            }

        } //link
    };

}); //appDatetime

Formumda şu şekilde kullanıyorum:

<label>begin: <input type="text" ng-model="doc.begin" app-datetime required /></label>
<label>end: <input type="text" ng-model="doc.end" app-datetime required /></label>

Bu, bir zaman damgasını (1970'ten beri geçen milisaniye) doc.beginve öğelerine bağlayacaktır doc.end.


1
Bu bağlantı işlevinin içinde ngModel, doğrudan, adlandırılmış bir referans değil, denetleyici argümanı için özel tanımlayıcınız olduğu gerçeğini gözden kaçırmak kolaydır ngModel. Bu, arg 'ctrl' veya 'controller' adlandırma kuralının işleri daha net tuttuğu ve karışıklığı önlediği bir noktadır.
XML

Teşekkürler! Bütün gün bunu yapmanın güzel bir yolunu arıyordum. Ne yazık ki, diğer birçok düzeltme, özellikle açısal için yazılmış bir tarih seçiciye geçmeyi içeriyordu ve bu çok fazla işti.
Josh Mouch

Hem seninkini hem de @SunnyShah'ın cevabını denedim ama onun cevabı işe yaramadı. Emin değilim neden.
Josh Mouch

3

Angular2 + 'da ilgilenen herkes için:

<input type="text" placeholder="My Date" [ngModel]="myDate | date: 'longDate'">

DatePipe Angular'daki filtre türleri ile .


Dang, üzerinde çalışmak zorunda kaldığım eski AngularJS'de sıkışıp kaldım ve bundan nefret ediyorum! Keşke çalışmak için yukarıdakiler olsaydı.
Jordan

Bu sadece insanları alay etmek ve onları Angular2 + kullanmaları için kandırmaktır. Yuck! AngularJs tamamen bomba. Neden kimse böyle basit bir çözüm ister ki?
Nebulosar

2

Sunucunun tarihi değiştirmeden döndürmesini ve görünüm masajını javascript'in yapmasını tercih ederim. API'm, SQL Server'dan "AA / GG / YYYY ss: dd: ss" döndürüyor.

Kaynak

angular.module('myApp').factory('myResource',
    function($resource) {
        return $resource('api/myRestEndpoint/', null,
        {
            'GET': { method: 'GET' },
            'QUERY': { method: 'GET', isArray: true },
            'POST': { method: 'POST' },
            'PUT': { method: 'PUT' },
            'DELETE': { method: 'DELETE' }
        });
    }
);

Kontrolör

var getHttpJson = function () {
    return myResource.GET().$promise.then(
        function (response) {

            if (response.myDateExample) {
                response.myDateExample = $filter('date')(new Date(response.myDateExample), 'M/d/yyyy');
            };

            $scope.myModel= response;
        },
        function (response) {
            console.log(response.data);
        }
    );
};

myDate Doğrulama Yönergesi

angular.module('myApp').directive('myDate',
    function($window) {
        return {
            require: 'ngModel',
            link: function(scope, element, attrs, ngModel) {

                var moment = $window.moment;

                var acceptableFormats = ['M/D/YYYY', 'M-D-YYYY'];

                function isDate(value) {

                    var m = moment(value, acceptableFormats, true);

                    var isValid = m.isValid();

                    //console.log(value);
                    //console.log(isValid);

                    return isValid;

                };

                ngModel.$parsers.push(function(value) {

                    if (!value || value.length === 0) {
                         return value;
                    };

                    if (isDate(value)) {
                        ngModel.$setValidity('myDate', true);
                    } else {
                        ngModel.$setValidity('myDate', false);
                    }

                    return value;

                });

            }
        }
    }
);

HTML

<div class="form-group">
    <label for="myDateExample">My Date Example</label>
    <input id="myDateExample"
           name="myDateExample"
           class="form-control"
           required=""
           my-date
           maxlength="50"
           ng-model="myModel.myDateExample"
           type="text" />
    <div ng-messages="myForm.myDateExample.$error" ng-if="myForm.$submitted || myForm.myDateExample.$touched" class="errors">
        <div ng-messages-include="template/validation/messages.html"></div>
    </div>
</div>

şablon / doğrulama / mesajlar.html

<div ng-message="required">Required Field</div>
<div ng-message="number">Must be a number</div>
<div ng-message="email">Must be a valid email address</div>
<div ng-message="minlength">The data entered is too short</div>
<div ng-message="maxlength">The data entered is too long</div>
<div ng-message="myDate">Must be a valid date</div>

1

Angularjs ui bootstrap angularjs ui bootstrap kullanabilirsiniz, ayrıca tarih doğrulama da sağlar

<input type="text"  class="form-control" 
datepicker-popup="{{format}}" ng-model="dt" is-open="opened" 
min-date="minDate" max-date="'2015-06-22'"  datepickeroptions="dateOptions"
date-disabled="disabled(date, mode)" ng-required="true"> 



denetleyicide tarihi tarih filtresi

$ kapsam.formats = ['gg-AAMM-yyyy', 'yyyy / AA / gg', 'gg.MM.yyyy', 'shortDate'] olarak görüntülemek istediğiniz formatı belirtebilirsiniz ;


sadece tek bir giriş alanı için direktif uygulamanıza gerek yok
P.JAYASRI
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.