AngularJS:为什么当父级有ngIf指令时,我不能向祖父元素添加属性
AngularJS: Why can't I add an attribute to grandparent element when parent has ngIf directive
我正在使用香草AngularJS v1.4.5(没有jQuery(,并希望我的自定义指令在编译时向其祖父元素添加一个属性。
在编译函数中,我可以使用parent()
方法来实现这一点,该方法element
两次以获取祖父元素,并使用attr()
方法来添加我的属性。但是,如果父元素具有 ngIf 指令,则祖父元素不会获取该属性。
angular.module('myApp', [])
.directive('foo', fooDirective)
;
function fooDirective() {
return {
compile : compile,
priority: 601 // ngIf is 600
};
function compile(element, attrs) {
var parent, grandparent;
parent = element.parent();
grandparent = parent.parent();
parent.attr('foo', 'bar');
grandparent.attr('foo', 'bar');
}
}
JSFiddle
以下是我所知道的:
- 如果未在父元素上使用
ngIf
,则该属性将添加到祖父元素中。 - 这个问题不应该与
scope
有关,因为这发生在编译阶段,在范围链接到任何元素之前。 - 我的编译函数应该在
ngIf
之前运行,它的优先级为600
(并且没有编译函数(。 -
ngIf
完全删除并重新创建 DOM 中的元素(及其子元素(,但这不应影响祖父元素或更改其属性。
谁能向我解释一下,如果父元素有 ngIf
指令,为什么我不能向指令的祖父元素添加属性?
所以,重申一下,问题是,为什么给出以下内容:
<grand-parent>
<parent ng-if="condition">
<foo></foo>
</parent>
</grand-parent>
当尝试从foo
的编译中检索var grandparent = tElement.parent().parent()
时,grandparent
不引用<grand-parent>
元素。
答案是因为ngIf
引起的隐含,即使condition === true
.
嵌入是将内容(或元素 + 内容,取决于嵌入的类型(从 DOM 中拉出、编译,然后作为克隆提供给嵌入函数的过程,该函数本身可用作link
函数的第 5 个参数:
link: function(scope, element, attrs, ctrls, transcludeFn){
transcludeFn(scope, function cloneAttachFn(clonedContent){
// clonedContent is the subtree that was transcluded, compiled and cloned
element.append(clonedContent);
});
}
因此,编译传递从 <grand-parent>
开始,然后转到 <parent>
,在那里它看到一个指令 - ngIf
。因为ngIf
有transclude: "element"
,所以它把<parent><foo></foo></parent>
从DOM中拉出来,并编译它。因此,编译继续编译<parent>
上的其他低优先级指令(如果可用(,然后编译foo
指令。
在这一点上,<foo>
没有受到<grand-parent>
,tElement.parent().parent()
收益率[]
。
我还不完全确定为什么会发生这种情况,但你有什么特殊的原因为什么要使用 compile 这样做吗?我调整了您的指令以使用链接,它似乎工作得很好。
(function () {
'use strict';
angular.module('myApp', [])
.directive('foo', fooDirective)
;
function fooDirective() {
return {
link : link,
priority: 601 // ngIf is 600
};
function link($scope, element, attrs) {
var parent, grandparent;
parent = element.parent();
grandparent = parent.parent();
parent.attr('foo', 'bar');
grandparent.attr('foo', 'bar');
}
}
})();
编辑:就像@NewDev说的那样,您通常应该在链接阶段而不是在编译期间进行DOM操作。
- 为什么在使用 removeEventListner 后不能添加 EventListener
- AngularJS,不能添加模块
- 为什么我的两个变量不能添加相同的对象?Javascript
- 如何在#之后添加文本,但不能添加#
- 不能添加JS文件,或任何其他,到钛项目文件夹
- 为什么不能添加字符串到javascript数组
- 为什么我不能添加一个元素,删除它,然后第二次添加相同的元素?
- 不能添加流星包
- 不能添加监听器
- Slick .js不能添加null错误
- 我不能添加一个类到标签,虽然它说ok
- 为什么我不能添加字段到JS对象
- 我不能添加信息到我的表在mysql.我使用javascript来显示信息消息,然后它不做任何事情
- 悬停功能生效时不能添加类
- 不能添加'1'在预谋
- 条纹:不能添加到表单动态创建的表格通过javascript
- 为什么Array不能添加带有字面量的原型
- w2ui: ERROR:不能添加没有记录的记录.(obj:网格)
- highchart不能添加series
- 纯HTML的Ajax响应不能添加到IE8中现有的dom元素的原因