Я с помощью пользовательского интерфейса.бутстрап.элемент управления datepicker]1 директива, чтобы отобразить некоторые поля даты. Однако большую часть времени мне нужна такая же установка: Я хочу, чтобы он пришел вместе с кнопкой всплывающем и всплывающем и также я хочу, чтобы немецкие названия для текстов. Что ли создать такой же код для кнопок и текста и форматирование снова и снова, поэтому я написал мои собственные директивы, чтобы предотвратить себя от повторения себя.
Вот plunkr с моей директивы. Однако я, кажется, делают это неправильно. Если вы выберете дату с помощью выбора даты и"Дата 1" и отмечать, что не использовать мое распоряжение все работает нормально.
Я'ожидать то же самое для даты 2, но вместо отображения даты по шаблону, я поставила в поле ввода (или любое другое значение я ожидал) он отображает .представление метода toString () из объекта Date (напр.
Пт апр 03 2015 00:00:00 по GMT+0200 (мск)`).
Вот моя директива:
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
};
});
И что's, как я использую это:
<input my-datepicker="" type="text" ng-model="container.two" id="myDP" />
(Концепции был вдохновлен этот ответ)
Я использую угловые 1.3 (в plunker на 1.2, потому что я только что выложил в plunker от угловые-интерфейс-загрузки документация управления datepicker). Я надеюсь, что это не имеет никакого значения.
Почему вывод текста в мой ввод не так и как это сделать правильно?
Обновление #
А пока я сделал немного прогресса. После прочтения больше о подробности о компиляции и компоновки, в этом plunkr я использую компиляции функции, а не функции связи, чтобы сделать моих манипуляций с DOM. Я до сих пор немного смущает этот отрывок из документации:
Примечание: экземпляр шаблон и экземпляр ссылке могут быть разные объекты, если шаблон был клонирован. По этой причине это не безопасно, чтобы сделать что-нибудь другое, чем преобразования дом, которые распространяются на все клонированные узлы DOM в компиляции функции. В частности, регистрация дом слушатель должен производиться в увязке функции, а не в компиляции функции.
Особенно интересно, что значит с ", которые применяются ко всем клонированные узлы и купили дом;. Я изначально думал, что это означает ", которые применяются ко всем клонам шаблона и купили дом; но это не представляется случай.
Во всяком случае, моей новой компиляции версии работает в Chromium. В Firefox мне нужно сначала выбрать дату с помощью выбора даты и после этого все работает нормально (проблема с Firefox решала сама, если я изменю неопределенное значение null (plunkr) в дату парсер для выбора даты). Так что это'т последней вещью либо. И кроме того, я использую НГ-звонит model2 "вместо" НГ-модель, которую я переименуйте во время компиляции. Если не делать этого все-таки разобьется. До сих пор не знаю, почему.
Если честно, я'м не совсем уверен, почему это'ы вызвало и то, что'ы в результате ваш день, чтобы быть "метод toString-Эд" и прежде чем показать его на входе.
Однако, я нашел места, чтобы реструктуризировать свои директивы, и удалить много ненужного кода, такие как $компиляции сервис, атрибутов меняется, сферу наследования,
требуют` в директиве, и т. д.. я использовал изолированный объем, так как я Дон'т думаю, что каждый директиве использование должны знать материнской сферы, так как это может вызвать порочный ошибок в будущем. Это мой изменил директиву:
angular.module('ui.bootstrap.demo').directive('myDatepicker', function() {
return {
restrict: 'A',
scope: {
model: "=",
format: "@",
options: "=datepickerOptions",
myid: "@"
},
templateUrl: 'datepicker-template.html',
link: function(scope, element) {
scope.popupOpen = false;
scope.openPopup = function($event) {
$event.preventDefault();
$event.stopPropagation();
scope.popupOpen = true;
};
scope.open = function($event) {
$event.preventDefault();
$event.stopPropagation();
scope.opened = true;
};
}
};
});
А использование HTML-документ:
<div my-datepicker model="container.two"
datepicker-options="dateOptions"
format="{{format}}"
myid="myDP">
</div>
Редактировать: добавлена идентификатор
в качестве параметра к директиве. Plunker была обновлена.
Ваша директива будет работать, когда вы добавляете эти 2 строки с определением директивы:
return {
priority: 1,
terminal: true,
...
}
Это связано с порядком, в котором директивы выполняются.
Так в вашем коде
<input my-datepicker="" type="text" ng-model="container.two" id="myDP" />
Существуют две директивы: ngModel
и myDatepicker
. Приоритетных вы можете сделать свои собственные директивы выполнить перед ngModel делает.
Я думаю, что ответ от @Омри-Аарон является лучшим, но я'd, как, чтобы указать на некоторые улучшения, которые не'т было сказано здесь:
Вы можете использовать config, чтобы равномерно установить такие параметры, как формат и параметры текста следующим образом:
angular.module('ui.bootstrap.demo', ['ui.bootstrap'])
.config(function (datepickerConfig, datepickerPopupConfig) {
datepickerConfig.formatYear='yy';
datepickerConfig.startingDay = 1;
datepickerConfig.showWeeks = false;
datepickerPopupConfig.datepickerPopup = "shortDate";
datepickerPopupConfig.currentText = "Heute";
datepickerPopupConfig.clearText = "Löschen";
datepickerPopupConfig.closeText = "Schließen";
});
Я считаю, это будет понятнее и проще обновлять. Это также позволяет значительно упростить директивы, шаблону и разметке.
angular.module('ui.bootstrap.demo').directive('myDatepicker', function() {
return {
restrict: 'E',
scope: {
model: "=",
myid: "@"
},
templateUrl: 'datepicker-template.html',
link: function(scope, element) {
scope.popupOpen = false;
scope.openPopup = function($event) {
$event.preventDefault();
$event.stopPropagation();
scope.popupOpen = true;
};
scope.open = function($event) {
$event.preventDefault();
$event.stopPropagation();
scope.opened = true;
};
}
};
});
<div class="row">
<div class="col-md-6">
<p class="input-group">
<input type="text" class="form-control" id="{{myid}}" datepicker-popup ng-model="model" is-open="opened" ng-required="true" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="open($event)"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
</div>
</div>
<my-datepicker model="some.model" myid="someid"></my-datepicker>
Далее, Если вы хотите использовать форматирование немецкого языка, вы можете добавить angular-locale_de.js. Это обеспечивает равномерность в использовании даты константы, такие как 'shortDate'
и вынуждает использовать немецкие названия месяцев и дней недели.
Вот мой патч обезьяны вашего plunker,
http://plnkr.co/edit/9Up2QeHTpPvey6jd4ntJ?p=preview
В основном то, что я сделал, чтобы изменить свою модель, которая является датой, чтобы вернуть отформатированную строку, используя директиву
.directive('dateFormat', function (dateFilter) {
return {
require:'^ngModel',
restrict:'A',
link:function (scope, elm, attrs, ctrl) {
ctrl.$parsers.unshift(function (viewValue) {
viewValue.toString = function() {
return dateFilter(this, attrs.dateFormat);
};
return viewValue;
});
}
};
});
Вам нужно пройти даты-формат атрибута для тега вашего "вклада".
Если бы я был тобой, я бы не пойти так далеко, чтобы сделать сложную директиву. Я бы просто добавить в <отмечать>
добавлен в тег ввод
с тем же НГ-модель, и показать/скрыть с помощью кнопки. Вы можете попробовать свой вариант, начиная с мой plunker
Если кто-то заинтересован в машинопись реализации (по мотивам @jme11's код):
Директивы:
'use strict';
export class DatePickerDirective implements angular.IDirective {
restrict = 'E';
scope={
model: "=",
myid: "@"
};
template = require('../../templates/datepicker.tpl.html');
link = function (scope, element) {
scope.altInputFormats = ['M!/d!/yyyy', 'yyyy-M!-d!'];
scope.popupOpen = false;
scope.openPopup = function ($event) {
$event.preventDefault();
$event.stopPropagation();
scope.popupOpen = true;
};
scope.open = function ($event) {
$event.preventDefault();
$event.stopPropagation();
scope.opened = true;
};
};
public static Factory() : angular.IDirectiveFactory {
return () => new DatePickerDirective();
}
}
angular.module('...').directive('datepicker', DatePickerDirective.Factory())
Шаблон:
<p class="input-group">
<input type="text" class="form-control" id="{{myid}}"
uib-datepicker-popup="MM/dd/yyyy" model-view-value="true"
ng-model="model" ng-model-options="{ getterSetter: true, updateOn: 'blur' }"
close-text="Close" alt-input-formats="altInputFormats"
is-open="opened" ng-required="true"/><span class="input-group-btn"><button type="button" class="btn btn-default" ng-click="open($event)"><i
class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
Использование:
<datepicker model="vm.FinishDate" myid="txtFinishDate"></datepicker>
При создании директивы является удобство, чтобы добавить атрибуты, которые вы можете иметь 2 директивы в исходном:
<input my-datepicker="" datepicker-popup="{{ format }}" type="text" ng-model="container.two" id="myDP" />
Потом избежать многих изолировать области путем изменения сферы деятельности: True " на " объем: falseв директиве
myDatepicker`.
Это работает, и я думаю, что это'ы предпочтительнее создавая дополнительные директивы для изменения даты ввода в нужный формат:
http://plnkr.co/edit/23QJ0tjPy4zN16Sa7svB?p=preview
Почему вы при добавлении атрибута в директиве причины этой проблемы я не знаю, это's почти как у вас 2 даты-комплектовщики на один и тот же вход, один формат и один с дефолтом, что вам'ы применяется после.
Использовать moment.js с UI-загрузочный компонент datepicker к Создать директиву, чтобы обеспечить всеобъемлющий набор шаблонов для форматов даты времени. Вы можете принять любой формат времени в изолированные области.
Я попытался сделать эту работу (несколько hack), что не может быть точно, что вы хотите, просто некоторые грубые идеи. Поэтому вам все равно придется настроить его немного. В plunker является:
`http://plnkr.co/edit/aNiL2wFz4S0WPti3w1VG?p=preview'
В принципе, я изменил директивы сфера, а также добавить часы для объем контейнера УАК.два.