为Angular指令创建的元素创建名称

时间:2014-11-05 20:28:04

标签: javascript angularjs twitter-bootstrap

对于我正在进行的项目,我创建了一个简化版的UI Bootstrap Calendar小部件。

Plunker of my Simplified Calendar, and how I'm using it, is here.

UI Bootstrap日历的一个有趣的方面是,即使它进入input[text],它仍然在date字典中为表单控制器生成$error验证,好像我在DOM中指定了一个input[date]元素。

然而,有很多子捕获量。你会在我的plunker的DOM中立即注意到的一件事是,当指定的日期字段实际上不是日期时,我已经指定了错误跨度(尝试输入一些像'cat'这样的值可笑的东西!)如果你输入的东西是不是日期,应该出现,但他们没有。

我尝试了一些方法来将正在创建的标记暴露给父级的名称字段:

  1. $transclude设置为false,以便<calendar></calendar>标记替换为calendar指令模板的内容,并指定name属性。这“工作”,除了所说的输入被包装在一个跨度中,该跨度具有使用Bootstrap样式框架看起来正确所必需的类。
  2. 使用绑定直接在name指令的输入字段中创建calendar属性,如此*:

    app.directive('mustPrecedeDate', [ function () { return { restrict: 'E', template: '<input type="text" name="{{ someName }}" />', scope: {}, controller: 'calendarCtrl', link: function () {} }; } };

  3. 编写link代码以显式查找作为calendar生成标记的子项的输入,并为其分配name属性。 2和3都失败了,因为显然这不是真正可以完成的事情(我找不到那个发现来源的SO问题。)

  4. 这导致我的问题:我可以通过什么方式获取输入元素的名称,以便可以将验证结果报告给$error字典,以便我可以给我的用户提供有用的验证消息?

    *:显然,带有“左边四个空格”格式的代码块在编号列表中表现不佳,所以我不得不使用反引号代码表示法来正确地格式化文本。如果我没有在标记设置中找到错误,请随时更正我的格式。

1 个答案:

答案 0 :(得分:0)

第三件事需要更加努力!

我可以通过在链接功能中添加以下代码来获取输入名称:

var inputElement = elem.find('input');
inputElement.attr('name', inputName);

...从属性列表中删除inputName的位置。我可以使用inputName函数将input[text]下移到生成的compile字段,如下所示。

app.directive('calendar', [
    function() {
        return {
            restrict: 'E',
            transclude: false,
            scope: {},
            template:
                '<span class="input-group">'
                    + '<input class="form-control" required '
                        + 'type="text" placeholder="MM/dd/yyyy" '
                        + 'data-ng-model="dt" data-ng-click="toggle($event)" '
                        + 'data-ng-change="updateParentProperty()" '
                        + 'datepicker-popup="MM/dd/yyyy" is-open="isOpen" />'
                    + '<span class="input-group-btn">'
                        + '<button type="button" class="btn btn-default" data-ng-click="toggle($event)">'
                            + '<i class="fa fa-calendar"></i>'
                        + '</button>'
                    + '</span>'
                + '</span>',
            controller: 'calendarCtrl',
            compile: function(elem, attrs) {
                var inputName = attrs.inputName;

                var inputElement = elem.find('input');
                inputElement.attr('name', inputName);

                // Compile returns a Link function!
                return function(scope, elem, attrs, ctrl) {
                    var modelName = attrs.ngModel;

                    scope.parentProperty = modelName;
                    scope.dt = scope.$parent[modelName];
                };
            }
        };
    }
]);