Я использую директиву ui.bootstrap.datepicker для отображения некоторого поля даты. Однако большую часть времени мне нужна такая же настройка: я хочу, чтобы она появилась вместе с всплывающим окном и кнопкой всплывающего окна, а также я хочу, чтобы немецкие имена тексты. Это снова и снова создает тот же код для кнопки и текстов и форматирования, поэтому я написал свою собственную директиву, чтобы я не повторял себя.
Вот планком с моей директивой. Однако я, кажется, делаю это неправильно. Если вы выбираете дату с помощью выбора даты, используя параметр даты "date 1", который не использует мою директиву, все работает нормально.
Я бы ожидал то же самое для Date 2, но вместо отображения даты в соответствии с шаблоном, который я предоставил в поле ввода (или любым другим ожидаемым значением), он отображает представление .toString()
объекта даты (например, Fri Apr 03 2015 00:00:00 GMT+0200 (CEST)
).
Вот моя директива:
angular.module('ui.bootstrap.demo').directive('myDatepicker', function($compile) {
var controllerName = 'dateEditCtrl';
return {
restrict: 'A',
require: '?ngModel',
scope: true,
link: function(scope, element) {
var wrapper = angular.element(
'<div class="input-group">' +
'<span class="input-group-btn">' +
'<button type="button" class="btn btn-default" ng-click="' + controllerName + '.openPopup($event)"><i class="glyphicon glyphicon-calendar"></i></button>' +
'</span>' +
'</div>');
function setAttributeIfNotExists(name, value) {
var oldValue = element.attr(name);
if (!angular.isDefined(oldValue) || oldValue === false) {
element.attr(name, value);
}
}
setAttributeIfNotExists('type', 'text');
setAttributeIfNotExists('is-open', controllerName + '.popupOpen');
setAttributeIfNotExists('datepicker-popup', 'dd.MM.yyyy');
setAttributeIfNotExists('close-text', 'Schließen');
setAttributeIfNotExists('clear-text', 'Löschen');
setAttributeIfNotExists('current-text', 'Heute');
element.addClass('form-control');
element.removeAttr('my-datepicker');
element.after(wrapper);
wrapper.prepend(element);
$compile(wrapper)(scope);
scope.$on('$destroy', function () {
wrapper.after(element);
wrapper.remove();
});
},
controller: function() {
this.popupOpen = false;
this.openPopup = function($event) {
$event.preventDefault();
$event.stopPropagation();
this.popupOpen = true;
};
},
controllerAs: controllerName
};
});
И как я его использую:
<input my-datepicker="" type="text" ng-model="container.two" id="myDP" />
(Концепция была вдохновлена этим ответом)
Я использую angular 1.3 (plunker находится на 1.2, потому что я просто разблокировал плункер из angular -ui-bootstrap документация датпикера). Надеюсь, это не имеет никакого значения.
Почему текст выводится на моем входе неправильно и как это делается правильно?
Update
Тем временем я сделал небольшой прогресс. После более подробного ознакомления с подробностями о компиляции и ссылке в this plunkr Я использую функцию компиляции, а не функцию ссылки, чтобы выполнять мои манипуляции с DOM. Я все еще немного смущен этой выдержкой из документов:
Примечание: экземпляр шаблона и экземпляр ссылки могут быть разными объектами, если шаблон был клонирован. По этой причине небезопасно делать что-либо другое, кроме преобразований DOM, которые применяются ко всем клонированным узлам DOM в функции компиляции. В частности, регистрация слушателя DOM должна выполняться в функции связывания, а не в функции компиляции.
Особенно интересно, что подразумевается под ", которые применяются ко всем клонированным узлам DOM". Первоначально я думал, что это означает, что это применимо ко всем клонам шаблона DOM, но это, похоже, не так.
Во всяком случае: Моя новая версия компиляции отлично работает с хромом. В Firefox мне нужно сначала выбрать дату, используя средство выбора даты, и после этого все будет хорошо (проблема с Firefox решена сама собой, если я изменю undefined на null (plunkr) в парсере даты выбора даты). Так что это тоже не последняя вещь. Кроме того, я использую ng-model2
вместо ng-model
, который я переименовываю во время компиляции. Если я этого не сделаю, все еще сломано. По-прежнему не знаю, почему.