这是对https://stackoverflow.com/a/24058594/261673的跟进,我在其中询问如何制定一个为ng-options
指令提供默认选项的指令。
我尝试提供默认值,以防ng-model
定义的值未定义。
我已将require: 'ngModel'
添加到指令选项,并将以下代码添加到link
函数返回的compile
函数中:
if(!$ctrl.$viewValue) {
$ctrl.$setViewValue($scope.months[0]);
}
其中$ctrl
为ngModelController
。如果我将优先级设置为0,那么可以正常工作(请参阅编辑),但是,如果我保留它原来的(1001
)它不再有效。我怀疑这个指令是在ngModel
之前编译的,因为它的terminal
ngModel
永远不会编译而且会中断。
有没有办法以某种方式使其工作而不将优先级更改为0?
这里有整个代码的Plunker:http://plnkr.co/edit/IZ0eyqHoqwSVPlhxI98X?p=preview
编辑:实际上,优先级0也不能正常工作。出于某种原因,每隔一次更改任何选择中的选项,该值将被取消定义,并且存在包含? undefined:undefined ?
和?
值的空选项...
答案 0 :(得分:1)
我不知道为什么原来的回答者认为他们必须使用terminal: true
,但你不必这样做。
所有你需要它来确保你的指令在select
指令(在优先级0执行)之前编译,所以任何优先级> 0都会这样做(事实上使用优先级1工作正常)。
然后您可以照常访问所需指令的控制器:
app.directive('myOptionsMonths', function ($timeout) {
return {
priority: 1,
require: 'ngModel',
compile: function (tElem, tAttrs) {
tAttrs.$set('ngOptions', 'month for month in months');
tAttrs.$set('myOptionsMonths', null);
return function (scope, elem, attrs, ctrl) {
scope.months = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
$timeout(function () {
if (ctrl.$viewValue === undefined) {
ctrl.$setViewValue(scope.months[0]);
}
});
};
}
};
});
<子>
您仍然需要使用$timeout
,因为NgModelController
的属性尚未设置
子>
另请参阅此 short demo 。
答案 1 :(得分:0)
我想我已经弄明白了,然而,它看起来像是一个可怕的黑客。
查看$compileProvider.directive
函数的源代码,我找到了一种在不使用ngModelController
的情况下访问require: 'ngModel'
的方法:
$timeout(function () {
var ctrl = $element['data']('$ngModelController');
if (ctrl.$viewValue) {
ctrl.$setViewValue($scope.months[0]);
}
});
它与之前的代码非常相似,但这次它可以通过编译元素访问ngModelController
。需要$timeout
,因为此时ctrl.$viewValue
总是NaN
,即使设置了模型值,也总是覆盖模型值。
这是更新的Plunker:http://plnkr.co/edit/h5ZPqTdyrZ0zTyyDcdei?p=preview