我对以某些字母(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 完成时)。

这种行为从何而来?

有帮助吗?

解决方案

这里涉及三种机制来解释这种行为:

  1. 观察者被处决 相同的订单 他们已注册(请参阅代码 $watch 方法()).

  2. 链接后函数在 相反的顺序 他们的优先级(请参阅文档 priority 财产).

  3. 具有相同优先级的指令以未定义的顺序执行。默认优先级是 0, ,因此您此处的所有自定义指令都具有此优先级。自从 select 指令也是优先事项 0, ,执行顺序未定义。

    正如您所注意到的,“未定义”有点过分,实际上执行的顺序是 按字母顺序 (看到 $compile 代码):名称位于字典开头的指令具有更高的优先级。但是,以我的愚见,由于文档中没有明确说明这一点, 你不能依赖这种行为.

总而言之,这里有一些用例。每个指令都会注册一个观察者。

  Name  |  Priority  | Watcher order
--------+------------+--------------
A       | 100        | 3rd
B       | 0          | 2nd
C       | none (= 0) | 1st

因此,解决这个问题很简单:

  • 如果您想执行自定义指令的观察者 select 一,只需给予您的指令高于 0.
  • 如果您想执行自定义指令的观察者 select 一,嗯……因为禁止负优先级,所以你不能可靠地做到这一点。
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top