角度引导的方式

时间:2014-04-30 10:08:01

标签: angularjs angularjs-scope

我对Angular bootstraps的方式有疑问。考虑这个指令:

app.directive('finder', function () {
    return {
        restrict: 'E',
        replace: true,
        template:'<div><input type="text" data-ng-model="my-input" style="width:80%;" /></div>',
        compile: function (element, attributes) {
            if (attributes.hasOwnProperty('required')) {
                element.removeAttr('required');
                element.find(':input').attr('required', true);
                element.removeClass("ng-invalid ng-invalid-required");
            }
            return {
                post: function postLink(scope, iElement, attributes) {
                    // Do some other stuff
                }
            }
        }
    }
})

我使用此指令如下:

<div>
  <finder required></finder>
</div>

一些CSS:

.ng-invalid-required {
  background: yellow;
}

正如您在指令中看到的那样,在编译阶段,我从元素中删除required属性,并将属性添加到input元素。结果是你应该期望的:主要元素不再具有该属性,但输入字段确实如此。

现在很奇怪&#39; part:输出显示div也有黄色背景。事实证明,主要元素(div)具有ng-invalid-required类!这很奇怪,因为我在编译阶段删除了required属性......

这怎么可能?

显然,Angular会扫描整个DOM以获取指令,并使用所属元素收集指令。扫描完成后,Angular将编译所有指令。有一次,它将编译我的finder指令。该指令删除所需的属性并将其添加到我的输入字段。稍后它会编译所需的属性。因为&#39;原始元素&#39;在收集的列表中,它将ng-invalid-required类添加到链接元素(div)。

这是对的吗?或者是否有这种行为的另一种解释?

编辑(感谢Nikos Paraskevopoulos在评论中提出的建议) 有趣的是:当我将其添加到指令中时:

 priority: 1000,
 terminal: true

它像我期望的那样工作。但是当我离开其中一个属性时,它再也不起作用了。有人可以向我解释为什么这有效吗?

2 个答案:

答案 0 :(得分:1)

“required”是在你的元素之前编译的,所以我认为即使你删除了必需的属性,它也已被标记为必需,angularjs会添加ng-invalid class。

尝试将指令的优先级更改为1000,因此它将在required指令之前编译,因此您可以删除所需的属性:

app.directive('finder', function () {
  return {
    priority: 100,
    restrict: 'E',
    ...
  };
});

答案 1 :(得分:1)

(从评论转到答案+解释)

尝试在指令定义中同时指定priority(以使指令在requiredDirective之前运行)和terminal: true

<强>解释

原始问题的原因是requiredDirective在元素上执行。显然,正如您所指出的,Angular会扫描整个DOM以获取指令并收集指令并执行它们。澄清一下:首先收集它们,然后执行它们。

这意味着,尽管您的requiredDirective功能删除了compile()属性,required仍会执行,因为Angular已经收集了&#34;&#34;指令。

terminal: true属性:

  

如果设置为true,则当前优先级将是将执行的最后一组指令

这意味着如果您将某个值设置为优先级,以便您的指令在 requiredDirective之前执行,则后者将根本不执行!显然,Angular 在遇到terminal: true的指令时会停止指令集合。