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

Creating names for elements created by an Angular directive

本文关键字:创建 元素 指令 Angular      更新时间:2023-09-26

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

我的简化日历的Plunker,以及我如何使用它,在这里。

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

然而,有一个捕获有许多子捕获。在我的plunker的DOM中,你会立即注意到一件事,那就是当给定的日期字段实际上不是日期时,我已经指定了错误范围(试着输入一些荒谬的东西,比如"cat"作为值!)如果你输入的不是日期,它们应该会出现,但它们不会。

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

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

    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问题,这是发现的来源。)

这就引出了我的问题:我如何才能将名称记到输入元素中,以便将验证结果报告给$error字典,以便向用户提供有用的验证消息?

*:显然,格式为"从左起四个空格"的代码块在编号列表中表现不佳,所以我不得不使用后引号代码表示法来使文本格式正确到一半。如果我在SO使用的降价设置中没有发现错误,请随时更正我的格式。

第三件事需要更加努力!

通过在链接函数中添加以下代码,我可以在输入中获得一个名称:

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

其中inputName是从属性列表中刮取的。通过使用下面的compile函数,我能够将inputName降到生成的input[text]字段。

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];
                };
            }
        };
    }
]);