Angular2 дата-дата не работает в IE 11 и краю 13/14
Я использую Angular 2.0 final, и у меня неправильный формат дат, когда я добавляю часы и минуты в строку формата:
В шаблоне компонента я:
<th id="lastexecution">{{dto.LastExecution | date:'yyyy-MM-dd HH:mm:ss'}}</th>
Дата выхода в IE 11:
2016-09-27 15:00:9/27/2016 3:53:46 PM:9/27/2016 3:53:46 PM
С {{dto.LastExecution | дата: 'YYYY-MM-дд'}}
Дата вывода в IE 11 верна:
2016-09-27
Вот версия компонентов, которые я использую в package.json:
{
"name": "ima_sentinel",
"version": "1.0.0",
"description": "QuickStart package.json from the documentation, supplemented with testing support",
"scripts": {
"start": "tsc && concurrently \"tsc -w\" \"lite-server\" ",
"docker-build": "docker build -t ima_sentinel .",
"docker": "npm run docker-build && docker run -it --rm -p 3000:3000 -p 3001:3001 ima_sentinel",
"pree2e": "npm run webdriver:update",
"e2e": "tsc && concurrently \"http-server -s\" \"protractor protractor.config.js\" --kill-others --success first",
"lint": "tslint ./app/**/*.ts -t verbose",
"lite": "lite-server",
"postinstall": "typings install",
"test": "tsc && concurrently \"tsc -w\" \"karma start karma.conf.js\"",
"test-once": "tsc && karma start karma.conf.js --single-run",
"tsc": "tsc",
"tsc:w": "tsc -w",
"typings": "typings",
"webdriver:update": "webdriver-manager update"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"@angular/common": "2.0.0",
"@angular/compiler": "2.0.0",
"@angular/core": "2.0.0",
"@angular/forms": "2.0.0",
"@angular/http": "2.0.0",
"@angular/platform-browser": "2.0.0",
"@angular/platform-browser-dynamic": "2.0.0",
"@angular/router": "3.0.0",
"@angular/upgrade": "2.0.0",
"angular2-in-memory-web-api": "0.0.20",
"bootstrap": "^3.3.6",
"core-js": "^2.4.1",
"linqts": "^1.6.0",
"reflect-metadata": "^0.1.3",
"rxjs": "5.0.0-beta.12",
"signalr": "^2.2.1",
"systemjs": "0.19.27",
"typescript-collections": "^1.1.9",
"zone.js": "^0.6.23"
},
"devDependencies": {
"concurrently": "^2.2.0",
"lite-server": "^2.2.0",
"typescript": "^2.0.2",
"typings": "^1.0.4",
"canonical-path": "0.0.2",
"http-server": "^0.9.0",
"tslint": "^3.7.4",
"lodash": "^4.11.1",
"jasmine-core": "~2.4.1",
"karma": "^1.2.0",
"karma-chrome-launcher": "^0.2.3",
"karma-cli": "^0.1.2",
"karma-htmlfile-reporter": "^0.2.2",
"karma-jasmine": "^0.3.8",
"protractor": "^3.3.0",
"rimraf": "^2.5.2"
},
"repository": {}
}
Ответы
Ответ 1
Это открытая проблема для Angular для этой проблемы - в качестве обходного пути я создал канал для использования форматирования момента вместо встроенный Angular:
import { Pipe, PipeTransform } from '@angular/core';
import * as moment from 'moment';
@Pipe({
name: 'datex'
})
export class DatexPipe implements PipeTransform {
transform(value: any, format: string = ""): string {
// Try and parse the passed value.
var momentDate = moment(value);
// If moment didn't understand the value, return it unformatted.
if (!momentDate.isValid()) return value;
// Otherwise, return the date formatted as requested.
return momentDate.format(format);
}
}
Что можно использовать:
{{exampleDate | datex:'DD/MM/YYYY HH:mm:ss'}}
Дата, в которую вы проходите, должна быть чем-то, что может проанализировать момент (см. соответствующую документацию по времени), а строка формата - момент, а не angular, строка форматирования даты, описанная здесь.
Я тестировал это в IE11, Chrome и Firefox, и он ведет себя последовательно.
Вам нужно будет убедиться, что момент добавлен в ваш пакет .json как зависимость, например:
{
"name": "demo",
"version": "0.0.1",
// snip
"dependencies": {
// snip
"moment": "^2.15.1",
// snip
},
"devDependencies": {
//snip
}
}
... и убедитесь, что ваш файл systemjs.config.js обновлен, чтобы он мог найти момент:
map: {
'moment': 'npm:moment'
}
packages: {
moment: { main: './moment.js', defaultExtension: 'js' }
}
Ответ 2
Из Angular2 Документация API DatePipe.
"эта труба использует API интернационализации, поэтому она надежна только в браузерах Chrome и Opera.
Ответ 3
Относительно ответа от @mark-hughes выше, с момента получения документации по API:
date_expression | Дата [: формат]
выражение - это объект даты или число (миллисекунды с эпохи UTC) или строку ISO
Ссылка
Таким образом, значение должно быть любым типом, и вы можете использовать moment().isValid()
для проверки типа значения
@Pipe({name: 'datex'})
export class DatexPipe implements PipeTransform {
transform(value: any, format: string = ""): string {
return moment(value).isValid()? moment(value).format(format) : value;
}
}
Ответ 4
Если вы работаете с показом AM/PM вместо 24-часового времени, другое допустимое обходное решение - это разбить форматирование на две части и использовать shortTime
или mediumTime
для отображения временной части:
{{dto.LastExecution | date:'yyyy-MM-dd'}} {{dto.LastExecution | date:'shortTime'}}
Это должно работать во всех основных браузерах, включая IE и Edge.
Ответ 5
Работа в Angular 5.x
В версии 5.x Angular эта проблема корректно работает в Edge (v.38.14393.1066.0) и в IE (v.11.1198.14393.0), протестируйте в своей версии!
Пример в реальном времени: Plunker Angular 5.x
Связанная проблема, которая решила проблему (если я нашел что-то непоследовательное): https://github.com/angular/angular/issues/9524
Ответ, который включает всю операцию Angular DatePipe.
Ответ 6
Нижеприведенное решение отлично работает для IE11 и хром. Нет необходимости создавать пользовательские каналы.
{{dto.createdTimeLocal | date:'dd MMM yyyy'}} {{dto.createdTimeLocal | date:'shortTime'}}
Ответ 7
moment.js для Angular
Ответ на отличный ответ - это то, что я использовал, пока не нашел это простое решение, которое хорошо документировано.
moment.js для Angular
Этот модуль работает с Angular 2.0 и выше.