javascript - angularjs moment tolka format


Jag har en ng-repeat som visar följande uttryck

{{date}} // 2-1-2017

När jag använder angular-moment

{{date | amDateFormat:'DD'}} 

Jag fick 1, vilket jag förväntade mig 2. Hur får jag Moment att förstå att mitt format faktiskt är dd-mm-yyyy och inte mm-dd-yyy i vyn? Jag vill inte parsa det på min controller-nivå eftersom det är komplicerat.

Svar #1

Enligt dokumentationen har AngularJs ett inbyggt filter för datum som kan användas med följande uppsättning:

{{ date_expression | date : format : timezone}}

Så att du kan använda det så här:

{{ date | date:'dd-MM-yyyy'}}

Men om du använder Moments datumfilter måste det vara ett Moment-datum (d.v.s. ett komplett datum med definierad tidszon) objekt och du kan filtrera det på samma sätt som Angular gör.

{{ date | amDateFormat:'dd-MM-yyyy' }}

Svar #2

Du kan använda Angulars inbyggda filter för datum (som föreslagits i andra svar), om din indata är:

  • ett JavaScript Date-objekt
  • ett nummer som representerar millisekunder (detta kan också vara en sträng)
  • en sträng i ISO 8601-format (t.ex. yyyy-MM-ddTHH:mm:ss.sssZ, yyyy-MM-dd osv)

Ditt date är en sträng med ett format som inte är ISO 8601, så du måste ändra sättet du tolkar 2-1-2017 till ett datum.

Du kan analysera din sträng i din controller med moment(String, String) som visas i följande exempel:

angular.module('MyApp',['angularMoment'])
.controller('AppCtrl', function($scope) {
  $scope.dates = [
    // Wrong way to parse string
    moment('2-1-2017').toDate(),
    // Parse string specifying format
    moment('2-1-2017', 'D-M-YYYY').toDate()
  ];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.9/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-moment/1.0.1/angular-moment.min.js"></script>

<div ng-app="MyApp" ng-controller="AppCtrl">
  <div ng-repeat="date in dates">
    <span>angular-moment: {{date | amDateFormat:'DD'}}</span>
    <span>angular date filter: {{date | date:"dd"}}</span>
  </div>
</div>

Om du inte vill ändra din controller kan du använda Angular Moment amParse-filtret. Som dokumentationen säger, detta filter:

Parsar ett datum med anpassat format till ett moment-objekt som kan användas med am-time-ago-direktivet och de andra filtren.

Så i ditt fall kan du använda koden som visas i följande exempel:

angular.module('MyApp',['angularMoment'])
.controller('AppCtrl', function($scope) {
  $scope.dates = [
    '2-1-2017', // February 2 2017
    '15-1-2017' // January 15 2017
  ];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.9/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-moment/1.0.1/angular-moment.min.js"></script>

<div ng-app="MyApp" ng-controller="AppCtrl">
  <div ng-repeat="date in dates">
    <span>angular-moment: {{date | amParse:'D-M-YYYY' | amDateFormat:'DD'}}</span>
  </div>
</div>