Angularjs 如果给定指令为“指令”,如何要求具有较低优先级的指令;终点站;?

Angularjs 如果给定指令为“指令”,如何要求具有较低优先级的指令;终点站;?,angularjs,angularjs-directive,Angularjs,Angularjs Directive,这是一个后续问题,我问如何制定一个指令,为ng options指令提供默认选项 我试图提供一个默认值,以防未定义ng model定义的值 我在指令选项中添加了require:'ngModel',并在compile函数返回的link函数中添加了以下代码: 如果(!$ctrl.$viewValue){ $ctrl.$setViewValue($scope.months[0]); } 其中,$ctrl是ngModelController。如果我将优先级设置为0,它可以正常工作(请参见编辑),但是,

这是一个后续问题,我问如何制定一个指令,为
ng options
指令提供默认选项

我试图提供一个默认值,以防未定义
ng model
定义的值

我在指令选项中添加了
require:'ngModel'
,并在
compile
函数返回的
link
函数中添加了以下代码:


如果(!$ctrl.$viewValue){
$ctrl.$setViewValue($scope.months[0]);
}

其中,
$ctrl
ngModelController
。如果我将优先级设置为0,它可以正常工作(请参见编辑),但是,如果我保持原来的状态(
1001
),它将不再工作。我怀疑这条指令是在
ngModel
之前编译的,因为它是
终端
ngModel
从未编译过,有些东西坏了

有没有一种方法可以在不将优先级更改为0的情况下使其工作

下面是Plunker的全部代码:

编辑:实际上,它在优先级为0的情况下也不能正常工作。由于某些原因,每秒钟更改任何select中的选项时,该值都会被取消定义,并且会出现带有
的空选项?未定义:未定义?
值…

我想我已经弄明白了,但是,它看起来像一个可怕的黑客

查看
$compileProvider.directive
函数的源代码,我找到了一种无需使用
require:'ngModel'
即可访问
ngModelController
的方法:

$timeout(function () {
  var ctrl = $element['data']('$ngModelController');

  if (ctrl.$viewValue) {
    ctrl.$setViewValue($scope.months[0]);
  }
});
它与前面的代码非常相似,但这次它通过编译元素访问
ngModelController
$timeout
是必需的,因为否则,
ctrl.$viewValue
此时始终是
NaN
,即使设置了模型值,它也总是覆盖模型值


下面是更新后的Plunker:

我不知道为什么最初的回答者认为他们必须使用
终端: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
的属性



另请参见,这个

为什么需要将其设置为
终端
?这就是我对原始问题答案的作者提出的问题:)据我所知,因为您正在向元素添加一个新指令(
ng options
),所以此时不希望编译任何其他指令。相反,您希望在添加
ng选项后编译整个元素。谢谢!正如我前面提到的,我认为
terminal:true
是为了确保在第一次编译过程中,只有这个指令被编译,其余指令在第二次编译过程中与第一次编译过程中添加的
ng选项一起被编译。这似乎是有道理的,但看起来并不是真的必要。编辑:我刚刚注意到,您的指令没有像我的指令那样显式编译元素,因此没有两个编译过程-这可能就是它不需要是终端的原因,更高的优先级就足够了。确切地说:)
terminal
不会阻止其他具有更高(或同等)优先级的指令被执行,因此,使用它没有多大意义。