如何为ui-bootstrap日期选择器创建一个angularJs包装指令?

12 浏览
0 Comments

如何为ui-bootstrap日期选择器创建一个angularJs包装指令?

我正在使用ui.bootstrap.datepicker指令来显示一些日期字段。然而,大部分时间我都需要相同的设置:我希望它能够带有一个弹出窗口和一个弹出窗口按钮,并且我希望文本使用德语名称。这样会导致重复编写按钮、文本和格式化的代码,所以我编写了自己的指令,以免重复劳动。

这是一个带有我的指令的plunkr示例。然而,我似乎做错了。如果您使用不使用我的指令的"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(
              '' +
                '' +
                  '' +
                '' +
              '');
          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
  };
});

这是我使用它的方式:


(该概念受到这个答案的启发)

我使用的是angular 1.3版本(plunker上使用的是1.2版本,因为我刚从angular-ui-bootstrap的日期选择器文档中fork了plunker)。我希望这不会有任何影响。

为什么我的输入框中的文本输出是错误的,应该如何正确处理?

更新

与此同时,我取得了一些进展。在阅读了关于编译和链接的更多细节后,在这个plunkr示例中,我使用了编译函数而不是链接函数来进行DOM操作。我对文档中的这段摘录仍然有些困惑:

注意:如果模板已经被克隆,那么模板实例和链接实例可能是不同的对象。因此,在编译函数中只能执行适用于所有克隆的DOM节点的DOM转换。特别是,DOM监听器的注册应该在链接函数中完成,而不是在编译函数中完成。

特别是我想知道"适用于所有克隆的DOM节点"是什么意思。我最初认为这意味着"适用于DOM模板的所有克隆",但似乎并不是这样。

无论如何:我的新编译版本在Chromium中运行良好。在Firefox中,我需要先使用日期选择器选择一个日期,然后一切正常(如果我在日期选择器的日期解析器中将undefined改为null (plunkr),则Firefox的问题自行解决)。所以这也不是最新的事情。此外,我使用ng-model2而不是ng-model,我在编译过程中将其重命名。如果我不这样做,一切仍然是错误的。仍然不知道为什么。

0