ng-model을 사용하여 날짜 형식을 지정하는 방법은 무엇입니까?


93

다음과 같이 정의 된 입력이 있습니다.

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

페이지의 다른 곳에 표시되도록 조작 된 항목 :

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

페이지가로드 될 때 생년월일은 Dec 22, 2009. 내 안에 볼 때, <input>로가 표시 것 Tue Dec 22 2009 00:00:00 GMT-0800 (Pacific Standard Time)같아요있는 JS가 렌더링하는 방법입니다Date 문자열로 객체.

첫째, Angular에게 날짜 <input>를 다음과 같이 표시하도록 어떻게 말 12/22/2009합니까? |filters내부 에 적용 할 수없는 것 같습니다 .ng-model속성 .

둘째, 날짜를 편집하자마자 원래 형식으로 유지하더라도 다른 텍스트 ( <td>)는 |date더 이상 필터 를 적용하지 않는 것 같습니다 . 갑자기 입력 텍스트 상자의 형식과 일치하도록 형식이 변경됩니다. |date모델이 변경 될 때마다 필터 를 적용하려면 어떻게해야 합니까?


관련 질문 :


나는 또한 그것에 문제가 있었지만 표준 js Date()함수를 사용하여 더 간단한 솔루션을 제공 $scope.departDate = new Date(); $scope.departTime = $scope.departDate.toTimeString().slice(0, 5);했습니다. AngularJS IMO에서 다른 필터 나 까다로운 해결 방법이 필요하지 않습니다.
boldnik 15.06.22

답변:


71

양식의 사용자 지정 유효성 검사 사용 http://docs.angularjs.org/guide/forms 데모 : http://plnkr.co/edit/NzeauIDVHlgeb6qF75hX?p=preview

포매터와 파서 및 MomentJS를 사용하는 지시문 )

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
저는 포매터와 파서의 작은 예제를 만들고 싶었습니다. 오늘 귀하의 질문 덕분에 그렇게 할 이유가 생겼습니다.
SunnyShah

1
@Mark, 두 번째 바이올린의 Nan 문제를 수정했습니다. ;)
SunnyShah

1
두 번째 접근 방식을 제거했습니다. 너무 버그가 많았습니다.
SunnyShah

1
변경시 지시문을 사용하여 추가 개선을 수행 할 수 있습니다. stackoverflow.com/questions/14477904/…
SunnyShah

7
@SunnyShah-정말 도움이 돼요, 정말 감사합니다. 당신이 왜 궁금 var dateFormat = attrs.moMediumDate;하지 var dateFormat = attrs.moDateInput;입력이 동적으로 초기 형식이 선택되지 않습니다 생성되지 않은 경우 moMediumDate 지금의 장소로 설정된 것 같지 않습니다.
toxaq 2013

37

다음은 매우 편리한 지시문 angular-datetime 입니다. 다음과 같이 사용할 수 있습니다.

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

또한 입력에 마스크를 추가하고 유효성 검사를 수행합니다.


1
이 지시문도 사용했습니다. 감사합니다. jQuery UI Datepicker와 함께 사용하는 경우 datetime="<format>"속성 값에 지정된 형식이 Datepicker의 dateFormat옵션에 지정된 형식과 일치 하는지 확인해야합니다 .
tylerwal 2015

1
몇 개의 찬성표만으로 여기에 완벽한 솔루션이 어떻게 가능한지 궁금합니다. 날짜가 너무 많아서 지금 바로 여기서 해결할 수 있습니다! 고마워 친구.
C0ZEN

2
기존 앵귤러 앱에 더 쉽게 포함 할 수 있도록 문서가 개선되면 더 많은 사람들이이 투표에 찬성 할 것이라고 확신합니다.
Joel Hansen

8

표준을 활성화하는 간단한 지시문을 만들었습니다. input[type="date"]AngularJS ~ 1.2.16에서 양식 요소가 올바르게 작동하도록 .

이봐: https://github.com/betsol/angular-input-date

그리고 여기에 데모가 있습니다 : http://jsfiddle.net/F2LcY/1/


안녕 @Lorenzo, 무슨 뜻이야? 자세히 설명해 주시겠습니까?
Slava Fomin II

월 년 일은 Mon Tue, Wen
Merlin의

@Lorenzo 나는 내가 이해하지 못합니다. 이 지시문은 현지화와 관련이 없습니다. 아마도 사용중인 서식 지정 기능은 브라우저 / 시스템에서 로케일 설정을 가져 오는 것입니다. 예제를 제공하면 도움을 드릴 수 있습니다 (jsfiddle).
Slava Fomin II

1
크롬 만 지원하면 안돼요.
GeminiYellow

이 지침의 목표는 모든 플랫폼을 지원하는 것입니다. 문제가있는 경우 GitHub 저장소에 문제를 생성하지 않는 이유는 무엇입니까? 나는 항상 모든 문제에 대응하고 있습니다.
Slava Fomin II

7

jquery datepicker를 사용하여 날짜를 선택하고 있습니다. 내 지시문은 날짜를 읽고 json 날짜 형식 (밀리 초 단위)으로 변환하여 ng-model형식화 된 날짜를 표시하는 동안 데이터에 저장하고 ng-model에 json 날짜 (밀리 초 단위)가있는 경우 내 포맷터가 jquery datepicker 형식으로 표시됩니다.

Html 코드 :

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

Angular 지시어 :

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

        }
    };
});

이런!! sooooo 많이 감사합니다 !! 나는이 대답과 같은 것을 문자 그대로 이틀 동안 찾고 있었지만 찾을 수 없었습니다! 락!
Michael Rentmeister 2015

환상적입니다. 나는 잠시 동안 이와 같은 것을 찾고 있었다. 내 솔루션에 materializecss를 사용하고 있습니다. 이과 필요에 따라 사람의 stubles 구체화이 지시어를 변환 할 경우, 그냥 교체 element.datepicker와 함께element.pickadate
IWI

7

datepicker를 클래스로 사용했기 때문에 Jquery datepicker 또는 이와 유사한 것을 사용하고 있다고 가정합니다.

moment.js를 전혀 사용하지 않고 순전히 datepicker 및 angularjs 지시문 만 사용하여 원하는 작업을 수행 할 수있는 방법이 있습니다.

Fiddle 에서 여기에 예제를 제공했습니다.

여기 바이올린에서 발췌 :

  1. Datepicker의 형식이 다르고 angularjs 형식이 다르므로 적절한 일치 항목을 찾아서 컨트롤에서 미리 선택하고 ng-model이 바인딩되는 동안 입력 필드에도 채워 져야합니다. 아래 형식은 'mediumDate'AngularJS 형식과 동일합니다 .

    $(element).find(".datepicker")
              .datepicker({
                 dateFormat: 'M d, yy'
              }); 
  2. 날짜 입력 지시문에는 사람이 읽을 수있는 날짜 형식을 나타내는 임시 문자열 변수가 있어야합니다.

  3. 페이지의 다른 섹션에 걸쳐 새로 고침 이벤트 등을 통해 발생해야 $broadcast하고 $on.

  4. 필터를 사용하여 사람이 읽을 수있는 형식으로 날짜를 표현하는 것은 ng-model에서도 가능하지만 임시 모델 변수를 사용합니다.

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

6

저와 대부분의 사용자를 매우 행복하게 만드는 다음 지침을 사용합니다! 구문 분석 및 형식 지정에 순간을 사용합니다. 앞서 언급 한 SunnyShah의 것과 약간 비슷해 보입니다.

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

내 양식에서는 다음과 같이 사용합니다.

<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>

이는 타임 스탬프 (1970 년 이후 밀리 초)를 doc.begin및에 바인딩합니다 doc.end.


1
이 링크 함수 내 ngModel에서 컨트롤러 인수에 대한 사용자 지정 식별자가 .NET에 대한 직접 명명 된 참조가 아니라는 사실을 간과하기 쉽습니다 ngModel. 이것은 arg 'ctrl'또는 'controller'를 명명하는 규칙이 일을 더 명확하게 유지하고 혼동을 피하는 지점입니다.
XML

감사! 나는 이것을 할 좋은 방법을 하루 종일 찾고 있었다. 불행히도 대부분의 다른 수정 사항은 앵귤러 용으로 특별히 작성된 날짜 선택기로 전환하는 것과 관련이 있으며 너무 많은 작업이었습니다.
Josh Mouch dec

나는 당신과 @SunnyShah의 대답을 모두 시도했지만 그의 대답은 작동하지 않는 것 같습니다. 이유가 확실하지 않습니다.
Josh Mouch dec

3

관심있는 사람을위한 Angular2 + :

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

DatePipe Angular 의 필터 유형으로 .


Dang, 나는 내가 작업을 강요받은 레거시 AngularJS에 갇혀 있고 싫어! 위와 같이 작업했으면 좋겠어요.
Jordan

이것은 단지 사람들을 놀리고 Angular2 +를 사용하도록 속이는 것입니다. 왝! AngularJs는 완전히 폭탄입니다. 왜 이런 간단한 해결책을 원할까요?
Nebulosar

2

서버가 수정하지 않고 날짜를 반환하도록하고 자바 스크립트가 뷰 마사지를 수행하도록하는 것을 선호합니다. 내 API는 SQL Server에서 "MM / DD / YYYY hh : mm : ss"를 반환합니다.

자원

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

제어 장치

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 유효성 검사 지시어

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>

template / validation / messages.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 부트 스트랩 angularjs UI 부트 스트랩 을 사용할 수 있으며 날짜 유효성 검사도 제공합니다.

<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"> 



컨트롤러에서 날짜를 표시하려는 형식을 datefilter

$ scope.formats = [ 'dd-MMMM-yyyy', 'yyyy / MM / dd', 'dd.MM.yyyy', 'shortDate']로 지정할 수 있습니다.


당신이 단지 하나의 입력 필드에 대한 지침을 구현 할 필요가 없습니다
P.JAYASRI
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.