题
我对以某些字母(t、u、v、w、y、z)开头的指令有一个非常具体的问题。该指令用于 select
元素并正在观察 ngOptions
变化。
什么时候 ngOptions
填充来自 Ajax 请求的数据,指令名称以某个字母开头,例如w,第二个监视回调在创建选择选项之前触发。如果指令名称以不同的字母(a、k、m、n)开头,则创建选项后将触发第二个监视回调。
这是一个示例 具有以不同字母开头的多个指令。打开控制台查看问题。
<select w-foo ng-model="bar" ng-options="o.name for o in options"></select>
app.controller("test", function ($scope, $timeout) {
// Emulate ajaxed options
$timeout(function () {
$scope.options = [{
name: "aaa",
id: 1
}, {
name: "bbb",
id: 2
}, {
name: "ccc",
id: 3
}];
}, 500);
});
app.directive("wFoo", function () {
return {
require: 'ngModel',
link: function (scope, element, attrs, ngModel) {
scope.$watch(attrs.ngOptions.replace(/.*in /, ""), function () {
console.log("w-foo ngOptions changed", element.html());
});
}
};
});
在上面的代码中, element.html()
将包含一个空的 option
在第一个监视回调(初始摘要)中,还将包含一个空的 option
在第二个摘要中(当 Ajax 完成时)。
这种行为从何而来?
解决方案
这里涉及三种机制来解释这种行为:
观察者被处决 相同的订单 他们已注册(请参阅代码
$watch
方法()).链接后函数在 相反的顺序 他们的优先级(请参阅文档
priority
财产).具有相同优先级的指令以未定义的顺序执行。默认优先级是
0
, ,因此您此处的所有自定义指令都具有此优先级。自从select
指令也是优先事项0
, ,执行顺序未定义。正如您所注意到的,“未定义”有点过分,实际上执行的顺序是 按字母顺序 (看到
$compile
代码):名称位于字典开头的指令具有更高的优先级。但是,以我的愚见,由于文档中没有明确说明这一点, 你不能依赖这种行为.
总而言之,这里有一些用例。每个指令都会注册一个观察者。
Name | Priority | Watcher order
--------+------------+--------------
A | 100 | 3rd
B | 0 | 2nd
C | none (= 0) | 1st
因此,解决这个问题很简单:
- 如果您想执行自定义指令的观察者 后 这
select
一,只需给予您的指令高于0
. - 如果您想执行自定义指令的观察者 前 这
select
一,嗯……因为禁止负优先级,所以你不能可靠地做到这一点。
不隶属于 StackOverflow