我正在包装HTML"选择"我自己的指令元素。该指令应创建一个下拉菜单,表示它的选项。
我使用自定义" arBootstrapSelect"标记select元素。指令/属性。 该指令附加一个下拉菜单,其中的选项由ng-repeat重复。
"选项" "选择"中的元素元素用" arBootstrapSelectOption"标记。他们应该有一个"内容" attribute,表示动态指令。应编译此动态指令并在下拉菜单中显示。
基本上,每个选项(由" arBootstrapSelectOption"标记)都会编译它的内容"使用$ compile服务的属性并将其注入生活在arBootstrapSelect指令中的列表中。之后,arBootstrapSelect应使用ng-repeat显示已编译的选项。希望它不会太复杂。 我得到了Error Link
HTML:
<select ar-bootstrap-select class="form-control">
<option ar-bootstrap-select-option value={{$index}} ng-repeat="c in countries" content="<ar-country country-id='{{$index}}'></ar-country>">
</option>
</select>
<div class="dropdown">
<button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
Dropdown
<span class="caret"></span>
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
<li ng-repeat="option in arBootstrapSelectOptions">
{{option[1]}}
</li>
</ul>
</div>
我的指示:
(function () {
'use strict';
var app = angular.module('mainApp');
app.directive('arBootstrapSelect', function ($interval, $compile) {
$scope.arBootstrapSelectOptions = [];
function link(scope, element, attrs) {
//element.hide();
}
return {
restrict: 'A',
link: link,
scope: true
}
});
app.directive('arBootstrapSelectOption', function ($compile) {
function link(scope, element, attrs) {
scope.arBootstrapSelectOptions.push([attrs.value, $compile(attrs.content)(scope)]);
}
return {
scope: true,
restrict: 'A',
link: link,
}
});
})();
这很有效,但它很丑陋而且很慢:
(function () {
'use strict';
var app = angular.module('mainApp');
app.directive('arBootstrapSelect', function ($interval, $compile) {
//$scope.arBootstrapSelectOptions = [];
function link(scope, element, attrs) {
//element.hide();
scope.$on('arBootstrapSelectNewItem', function (event, data) {
var test = $('<li></li>').append(data);
element.parent().find('.dropdown-menu').append(test);
});
}
return {
restrict: 'A',
link: link,
scope: true,
transclude: true
}
});
app.directive('arBootstrapSelectOption', function ($compile) {
function link(scope, element, attrs) {
//scope.arBootstrapSelectOptions.push([attrs.value, $compile(attrs.content)(scope)]);
scope.$emit('arBootstrapSelectNewItem', $compile(attrs.content)(scope));
}
return {
scope: true,
restrict: 'A',
link: link
}
});
})();
答案 0 :(得分:0)
我不完全理解你的具体例子,所以我会在概念层面回答。
似乎在高层次上您只想为ng-repeat
指定用户提供的模板(例如<ar-country country-id='{{$index}}'>
)并将其放在指令提供的模板中(例如{{1}内) 1}})。
将模板作为内容提供,而不是作为属性,将更容易,更便于用户使用。然后,您只需要转换内容。 (我在这里避免使用<li>
,因为它本身就是一个指令而且我不明白你想要做什么 - 我将使用<option>
代替:
<my-option>
指令看起来像这样:
<my-option ng-repeat="c in countries">
<ar-country country-id='{{$index}}'></ar-country>
<my-option>
这将在概念上创建以下HTML:
.directive("myOption", function(){
return {
scope: true,
transclude: true,
template: '<li ng-transclude></li>'
}
});
(指令<my-option>
<li><ar-country country-id="0"></ar-country></li>
</my-option>
<my-option>
<li><ar-country country-id="1"></ar-country></li>
</my-option>
..
也将被编译和链接,并可能生成自己的内容)
此外,如果家长需要注册每个孩子,最好使用arCountry
进行沟通,而不是require
/ $emit
。因此,$on
需要定义一个具有注册子项的函数的控制器。而且,如果您需要提供其他模板,请转换内容:
parent
<my-select>
<my-option ng-repeat="c in countries>
<ar-country country-id='{{$index}}'></ar-country>
</my-option>
</my-select>
要使用.directive("mySelect", function(){
return {
scope: true,
transclude: true,
template: '<h1>heading</h1><div ng-transclude></div>',
controller: function(){
// this can be called by the child
this.registerChild = function(childElement, childController){
// store the children, if needed
}
}
}
});
,我们需要this.registerChild
使用require
:
myOption