我正在尝试在我的应用程序中的ng-options
元素中动态插入<select>
指令,这些指令都有自己的类名和其他指令(如ng-if
等)。< / p>
<div ng-app="app" ng-controller="ctrl">
<select ng-model="model" class="myClass" ng-if="condition || true" my-directive>
</select>
<pre>{{ model | json }}</pre>
</div>
angular
.module('app', [])
.directive('myDirective', function($compile) {
return {
restrict: 'A',
scope: false,
link: function($scope, $elem, $attr) {
$scope.items = [{ label: "foo", value: "foofoo"},
{ label: "bar", value: "barbar"}];
$elem.removeAttr('my-directive'); // Prevents infinite loop
$elem.attr('ng-options', 'item as item.label for item in items');
$compile($elem)($scope);
}
}
})
.controller('ctrl', function($scope) {
$scope.model = null;
$scope.$watch('model', function(val) { console.log('•', val) });
});
我的想法是my-directive
应该被ng-options
替换,并且该元素应该仍然像应用所有其他指令一样正常。
我不明白为什么ng-model
没有得到更新,因为指令的范围是父范围(scope: false
)。我试图在指令的compile
步骤中进行DOM修改,但$scope.items
未知,甚至没有填充下拉列表。
答案 0 :(得分:0)
你的主要问题是你需要设置你的指令的高优先级,以使其编译功能在ngModel之前执行(和ngIf也是如此)。为此,不要手动编译,而是实现指令的编译功能:
.directive('myDirective', function($compile) {
return {
priority: 10000,
terminal: true,
link: function(scope, element) {
element.attr('ng-options', 'item as item.label for item in items').removeAttr('my-directive');
$compile(element)(scope);
}
}
})
您还需要记住,如果您使用创建新范围的指令(如ngIf,ngInclude等),当模型不能更新时,您可能会遇到意外行为,因为Angular会将值写入子级&#39 ;范围模型。在您的演示中,我使用$parent
明确地引用了适当的范围,但最好使用controllerAs表示法来消除此类问题。
您也不想在指令链接功能中设置项目,但我想这只是为了演示目的,您应该将它移动到控制器。