Изменение формата MD-datepicker в угловом материале


угловой материал представил новый компонент выбора даты найден здесь.

Я хочу, чтобы дата, возвращаемая этим компонентом, была в формате yyy-mm-dd но я не уверен, как это делается. Путем поиска я нашел, что $mdDateLocaleProvider можно использовать, но я не смог найти пример его использования.

может кто-то показать мне рабочий пример форматирования даты, возвращенной md-datepicker?

12 54

12 ответов:

есть документация $mdDateLocaleProvider в угловых материальных документах.

angular.module('app').config(function($mdDateLocaleProvider) {
    $mdDateLocaleProvider.formatDate = function(date) {
       return moment(date).format('YYYY-MM-DD');
    };
});

Если вы не используете момент.js, замените код внутри formatDate за то, что вы хотите использовать для форматирования даты.

здесь является примером CodePen на основе образцов из угловых документов материала.

чтобы также решить проблему, указанную казуаром:

к сожалению, это не работает, если дата вводится с клавиатуры

вы также должны определить метод parseDate. Из документов:

$mdDateLocaleProvider.parseDate = function(dateString) {
    var m = moment(dateString, 'L', true);
    return m.isValid() ? m.toDate() : new Date(NaN);
};

для полного примера, у меня есть в моем приложении (используя момент):

$mdDateLocaleProvider.formatDate = function(date) {
    return moment(date).format('DD/MM/YYYY');
};

$mdDateLocaleProvider.parseDate = function(dateString) {
    var m = moment(dateString, 'DD/MM/YYYY', true);
    return m.isValid() ? m.toDate() : new Date(NaN);
};

в отношении

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

.config(function($mdDateLocaleProvider) {
  $mdDateLocaleProvider.formatDate = function(date) {

    var day = date.getDate();
    var monthIndex = date.getMonth();
    var year = date.getFullYear();

    return day + '/' + (monthIndex + 1) + '/' + year;

  };
});

отлично работал, когда дата набирается из keyborard и возвращается null в инициализации, чтобы избежать массажа "недопустимая дата" в директиве md-datapicker:

$mdDateLocaleProvider.formatDate = function(date) {
  return date ? moment(date).format('DD/MM/YYYY') : null;
};

$mdDateLocaleProvider.parseDate = function(dateString) {
  var m = moment(dateString, 'DD/MM/YYYY', true);
  return m.isValid() ? m.toDate() : new Date(NaN);
};

изменение формата даты, названия месяцев и названий недель во время выполнения вполне возможно с AngularJS 1.5.9 и момент 2.17.1.

сначала настройте исходный язык. (В этом примере конфигурация angular-translate / $translateProvider является необязательной.)

angular.module('app').config(configureLocalization)

configureLocalization.$inject = ['$translateProvider', '$mdDateLocaleProvider', 'localdb', '__config'];
function configureLocalization($translateProvider, $mdDateLocaleProvider, localdb, __config) {
  // Configure angular-translate
  $translateProvider.useStaticFilesLoader({
      prefix: 'locale/',
      suffix: '.json'
  });
  // get the language from local storage using a helper 
  var language = localdb.get('language');
  if (!language || language === 'undefined') {
    localdb.set('language', (language = __config.app.defaultLanguage));
  }
  // Set the preferredLanguage in angular-translate
  $translateProvider.preferredLanguage(language);

  // Change moment's locale so the 'L'-format is adjusted.
  // For example the 'L'-format is DD.MM.YYYY for German
  moment.locale(language);

  // Set month and week names for the general $mdDateLocale service
  var localeData = moment.localeData();
  $mdDateLocaleProvider.months      = localeData._months;
  $mdDateLocaleProvider.shortMonths = moment.monthsShort();
  $mdDateLocaleProvider.days        = localeData._weekdays;
  $mdDateLocaleProvider.shortDays   = localeData._weekdaysMin;
  // Optionaly let the week start on the day as defined by moment's locale data
  $mdDateLocaleProvider.firstDayOfWeek = localeData._week.dow;

  // Format and parse dates based on moment's 'L'-format
  // 'L'-format may later be changed
  $mdDateLocaleProvider.parseDate = function(dateString) {
    var m = moment(dateString, 'L', true);
    return m.isValid() ? m.toDate() : new Date(NaN);
  };

  $mdDateLocaleProvider.formatDate = function(date) {
    var m = moment(date);
    return m.isValid() ? m.format('L') : '';
  };
}

позже у вас может быть некоторый базовый контроллер, который наблюдает за языковой переменной, которая изменяется, когда пользователь выбирает другой язык.

angular.module('app').controller('BaseCtrl', Base);

Base.$inject = ['$scope', '$translate', 'localdb', '$mdDateLocale'];
function Base($scope, $translate, localdb, $mdDateLocale) {

  var vm = this;
  vm.language = $translate.use();

  $scope.$watch('BaseCtrl.language', function(newValue, oldValue) {
    // Set the new language in local storage
    localdb.set('language', newValue);
    $translate.use(newValue);

    // Change moment's locale so the 'L'-format is adjusted.
    // For example the 'L'-format is DD-MM-YYYY for Dutch
    moment.locale(newValue);

    // Set month and week names for the general $mdDateLocale service
    var localeDate = moment.localeData();
    $mdDateLocale.months      = localeDate._months;
    $mdDateLocale.shortMonths = moment.monthsShort();
    $mdDateLocale.days        = localeDate._weekdays;
    $mdDateLocale.shortDays   = localeDate._weekdaysMin;
    // Optionaly let the week start on the day as defined by moment's locale data
    $mdDateLocale.firstDayOfWeek = localeData._week.dow;
  });
}

обратите внимание, как нам не нужно менять элемент $mdDateLocale.formatDate и $mdDateLocale.parseDate методы, как они уже настроены для использования'L' -формат, который изменяется путем вызова moment.locale(newValue).

см. документацию для $mdDateLocaleProvider для дополнительной настройки локали:https://material.angularjs.org/latest/api/service/ $mdDateLocaleProvider

бонус: вот как может выглядеть селектор языка:

<md-select ng-model="BaseCtrl.language" class="md-no-underline">
  <md-option
    ng-repeat="language in ['en', 'de', 'fr', 'nl']"
    ng-value ="language"
  ><span
    class    ="flag-icon flag-icon-{{language ==='en' ? 'gb' : language}}"
  ></span>
  </md-option>
</md-select>

-- когда мы используем MD-DatePicker в MD-dialog, то $ mdDateLocaleProvider service не форматирует дату так, как нам нужно. Мы должны использовать $mdDateLocale в контроллере MD-dialog для форматирования даты MD-DatePicker. например -

angular.module('MyApp').controller('AppCtrl', function($scope, $mdDateLocale) {

  $mdDateLocale.formatDate = function(date) {
    return moment(date).format('YYYY-MM-DD');
  };

  $scope.myDate = new Date('2015-10-15');

  $scope.minDate = new Date();

  $scope.maxDate = new Date();
});

используя $filter вместо moment.js и в отношении ответов от @ Ian Poston Framer и @java dev для меня, наконец, сработало следующее:

angular
    .module('App', ['ngMaterial'])
    .run(function($mdDateLocale, $filter) {
        $mdDateLocale.formatDate = function(date) {
            return $filter('date')(date, "dd-MM-yyyy");
        };
    })

Я не мог сделать инъекцию $filter на.config потому что это не провайдер, поэтому я должен был сделать это внутри .run С $mdDateLocale.

Я хотел бы предоставить свое решение, которое на 100% основано на пост Кристиана Вестербека. Мне очень нравится то, что он сделал, но я лично хотел что-то более упрощенное.

appConfig.js

// config params in global scope that need to be set outside of Angular (due to Angular limitiations)
var appConfig = {
    // enables the dynamic setting of md-datepicker display masks (eg. when user changes language from English to Spanish)
    date: {
        // default mask
        format: "MM/dd/yyyy",

        // md-datepicker display format
        mdFormatDate: function (date) {
            if (date && date instanceof Date) {
                return date.format(appConfig.date.format);

            } else {
                return null;

            }

        }

    }

};

приложение.материал.конфиг.js

// set angular material config
app.config(['$mdDateLocaleProvider', function ($mdDateLocaleProvider) {
    // this is a global object set inside appConfig.js
    $mdDateLocaleProvider.formatDate = appConfig.date.mdFormatDate;

}]);

некоторый файл сервиса, который имеет дело с локализацией / переводами / etc

// inside the service where you'd track the language/locale change
service._updateConfigDateFormat = function (theNewDateFormat) {
    // where theNewDateFormat is something like 'yyyy/MM/dd' or whatever
    daepConfig.date.format = theNewDateFormat;

};

следует отметить, что это решение будет не live переформатируйте значения отображения вашего md-datepicker. Он будет работать только тогда, когда модель изменяет значения.

у меня была такая же проблема и придумал это простое решение с помощью момент.js. Я использовал ng-change атрибут, который срабатывает при изменении даты.

внутри вашего HTML:

<md-datepicker ng-model="myDate" ng-change="dateChanged()"></md-datepicker>

внутри вашего контроллера:

$scope.dateChanged = function() {
    this.myDate = moment(this.myDate).format('YYYY/MM/DD');
}

на angular-material>= 5.x.x

рекомендуемый способ использования других пользовательских / предопределенных форматов дат описан в документации по угловым материалам:

https://material.angular.io/components/datepicker/overview#choosing-a-date-implementation-and-date-format-settings

пример реализации с использованием MomentJS для настройки и разбора отображения даты и времени формата:

...
import { MomentModule } from 'angular2-moment';

import { MatMomentDateModule, MomentDateAdapter, MAT_MOMENT_DATE_FORMATS } from '@angular/material-moment-adapter';
import { DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE} from '@angular/material/core';

...

// moment formats explanation: https://momentjs.com/docs/#/displaying/format/
export const MY_FORMATS = {
    parse: {
      dateInput: 'YYYY-MM-DD',
    },
    display: {
      dateInput: 'YYYY-MM-DD',
      monthYearLabel: 'MMM YYYY',
      dateA11yLabel: 'YYYY-MM-DD',
      monthYearA11yLabel: 'MMMM YYYY',
    },
  };

  ...

@Component({
    ...
    providers: [
        // `MomentDateAdapter` and `MAT_MOMENT_DATE_FORMATS` can be automatically provided by importing
        // `MatMomentDateModule` in your applications root module. We provide it at the component level
        // here, due to limitations of our example generation script.
        {provide: DateAdapter, useClass: MomentDateAdapter, deps: [MAT_DATE_LOCALE]},
        // {provide: MAT_DATE_FORMATS, useValue: MAT_MOMENT_DATE_FORMATS},
        {provide: MAT_DATE_FORMATS, useValue: MY_FORMATS}
    ]
})

...

в зависимости от вашей реализации, внутри компонента можно также использовать:

date = new FormControl(moment());

вы также должны установить библиотеку моментов и адаптер для углового:

https://www.npmjs.com/package/angular2-moment

npm install --save angular2-moment

https://www.npmjs.com/package/@angular/material-moment-adapter

npm установите --save @angular / material-moment-adapter

Если вы используете последнюю версию углового материала.затем js использует службу $mdDateLocale. В этом примере кода используется встроенный фильтр даты angular в качестве альтернативы использованию момента.библиотека js. Смотрите другие параметры формата даты с помощью сервиса angular $filter здесь по этой ссылкеhttps://docs.angularjs.org/api/ng/filter/date.

// mainController.js
angular.module('app').config(function($mdDateLocale, $filter, $scope) {

  // FORMAT THE DATE FOR THE DATEPICKER
  $mdDateLocale.formatDate = function(date) {
        return $filter('date')($scope.myDate, "mediumDate");
  };

});

Я $mdDateLocaleProvider чтобы отформатировать его на конце фронды. Если вы хотите отформатировать дату при отправке ее на задний план, для меня сработало следующее : -

$filter('date')(this.date, 'MM/dd/yyyy');

у меня есть выше в контроллер.