我正在尝试创建一个指令,如果我声明:
<input my-directive show-button-bar="true" ng-model="fooBar"\>
它将创建以下HTML:
<div on-toggle="toggled(open)" is-open="dpModel.displayDatePicker" dropdown="" class="btn-group ng-scope">
<input my-directive show-button-bar="true" ng-model="fooBar"\>
<ul ng-click="$event.stopPropagation()" class="dropdown-menu datepicker-popup dropdown-menu-right">
<div ng-if="showButtonBar">
<div role="group" class="btn-group pull-left">
<button ng-click="setToday()" class="btn btn-xs btn-info" type="button">Today</button>
<button ng-click="clear()" class="btn btn-xs btn-danger" type="button">Clear</button>
</div>
<button ng-click="toggled(false)" class="btn btn-xs pull-right btn-success" type="button">Done</button>
</div>
</ul>
</div>
以下是我的指令中的代码片段,我尝试实现此目的:
var dropdown = $compile(angular.element('<div class=\"btn-group\" dropdown is-open=\"dpModel.displayDatePicker\" on-toggle=\"toggled(open)\"/>'))(scope);
var ulTemplate = '<ul id=\"list2\"ng-if=\"showButtonBar\" class=\"dropdown-menu datepicker-popup\" ng-class=\"direction === \'right\' ? \'dropdown-menu-right\':\'dropdown-menu-left\'\" role=\"menu\" ng-click=\"$event.stopPropagation()\">' +
'<li ng-if=\"dpModel.displayDatePicker\">' +
'<datepicker ng-model=\"dpModel.value\" show-weeks=\"false\"></datepicker>' +
'</li>' +
'<div ng-if=\"showButtonBar\">' +
'<div class=\"btn-group pull-left\" role=\"group\">' +
'<button type=\"button\" class=\"btn btn-xs btn-info\" ng-click=\"setToday()\">Today</button>' +
'<button type=\"button\" class=\"btn btn-xs btn-danger\" ng-click=\"clear()\">Clear</button>' +
'</div>' +
'<button type=\"button\" class=\"btn btn-xs pull-right btn-success\" ng-click=\"toggled(false)\">Done</button>' +
'</div>' +
'</ul>';
var ul = $compile(angular.element(ulTemplate))(scope);
element.wrap(dropdown);
ul.insertAfter(element);
我遇到的问题是ul部分
var ul = $compile(angular.element(ulTemplate)(scope))
将正确编译范围,但包装器部分dropdown
无法正确获取范围。这怎么可能?我做错了什么?
更新: 忘了还提到我需要在输入字段上有一个ng-model。
答案 0 :(得分:0)
[编辑]
第一个例子中有错误。它应该是$ attrs。$ attr [this.name]而不是$ attrs [this.name]。 这是一个使用模板返回函数的清理返回示例: http://jsfiddle.net/numtpyL7/2/
module.directive('myDirective', function () {
var wrapperTemplate = '\
<div>\
<ul>\
<li>Some Text</li>\
</ul>\
</div>';
return {
template: function($element, $attrs) {
var directiveTag = $attrs.$attr[this.name];
var inputElem = $element.clone().removeAttr(directiveTag);
var replacementHtml = angular.element(wrapperTemplate);
replacementHtml.prepend(inputElem);
return replacementHtml[0].outerHTML;
},
replace: true,
priority: 999999
};
});
[原文]
在高优先级终端指令中使用$ compile是这样的方法。 高优先级和终端意味着它将首先在元素上运行,并且它下面的任何内容都不会运行。然后在指令编译代码中从元素中删除该指令,用新DOM包装它,并用它替换当前元素。
module.directive('myDirective', function ($compile) {
var wrapperTemplate = '\
<div on-toggle="toggled(open)" is-open="dpModel.displayDatePicker" dropdown="" class="btn-group ng-scope">\
<ul ng-click="$event.stopPropagation()" class="dropdown-menu datepicker-popup dropdown-menu-right">\
<div ng-if="showButtonBar">\
<div role="group" class="btn-group pull-left">\
<button ng-click="setToday()" class="btn btn-xs btn-info" type="button">Today</button>\
<button ng-click="clear()" class="btn btn-xs btn-danger" type="button">Clear</button>\
</div>\
<button ng-click="toggled(false)" class="btn btn-xs pull-right btn-success" type="button">Done</button>\
</div>\
</ul>\
</div>';
return {
terminal: true,
priority: 999999,
compile: function($element, $attrs) {
// Remove this directive from the new wrapped template so that it does not get run again.
var inputElement = $element.removeAttr($attrs.$attr[this.name]);
// Add the new template to the DOM and remove the DOM of the current directive
var replacementHtml = angular.element(wrapperTemplate).prepend(inputElement.clone());
$element.after(replacementHtml);
$element.remove();
var subLink = $compile(replacementHtml);
return {
pre: function(scope, element, attrs) {
subLink(scope);
},
post: function(scope, element, attrs) {
}
}
}
};
});
答案 1 :(得分:-1)
这是因为在.wrap()
内部克隆了下拉元素。虽然它仍然与范围绑定,但这对内部表达式和指令没有影响,必须重新编译。更简单的解决方案是创建包装<my-directive>
,以便下拉列表成为此结构中最顶层的元素。可以使用transclude插入input
。
<div my-directive><input show-button-bar="true"></div>
//within directive
return {
transclude: true,
template: '<div class="btn-group" dropdown is-open="dpModel.displayDatePicker" on-toggle="toggled(open)">' +
'<ng-transclude></ng-transclude>' +
'<ul ...></ul>' + // UL template goes here
'</div>',
link: function (scope, element) {
//... link function code
}
}
在这种情况下,你似乎不需要编译。