求助,关于angular在指令中无法获取子元素的

如题所述

因为在一个directive被link的时候,其内部的directive,是还没有被执行的。
对于ng-model这类的directive还好,那个元素是还在的。
而对于ng-repeat而言则不一样,为了优化,让ng-repeat只被compile一次,它会在compile阶段把这个节点摘除掉,单独compile一次,然后在发生数据绑定的时候对每个实例单独进行link。
用楼上同学的$timeout大法的确是可以的,不过个人不是很建议,因为这样就变成单次绑定了。
你这样获取子元素对于angular来说是非常不建议的,身为一个男人,你必须对ng-repeat的后果负责(雾),它是动态绑定的,意味着它里面的内容会变,如果你只获取一次,那它变了,你没响应,就是不负责任的表现。另一个,你的父directive里对其内容有依赖,这是非常糟糕的实践。
angular给你了一个监听变化的机会,是通过对数据变化的监听。其实是可行的,但是我也不建议这么用。一是在$watch当中你需要维护一个元素它是新的还是旧的,比如避免重复绑事件。二是这样对于$scope里的数据字段结构依然是耦合的,而且也没有解决DOM结构依赖的问题,你的父directive还是没有复用性可言。
所以个人建议如果一个directive是作为容器,那么它不应该对任何它的内容有依赖。如果是作为装饰者,应只作用于元素本身,而不作用于其子元素。
那么如果想实现一个轮播图slides怎么办?很明显slides的内容是很适合通过ng-repeat动态绑定的,我现在希望如果定义一个slides组件,它的内容就会被以轮播图的形式展现。这时候很明显是组件对其内容有依赖。
这里参考angular-ui-bootstrap当中的tabset实现举个例子:再定义一个名为slide-item的directive,在它的声明当中require: '^slides',这样变成了子组件依赖父组件。在slides当中定义add, remove, select等API,在slide-item被link的时候调用其父的add来修改数据,并且再通过转交transclude函数的方式把自己的内容交给slides来处理。这样做到了:
1、slides可以动态包含任意多的slide-item
2、slide-item可以transclude任意的内容
从依赖关系上看,slide-item依赖slides完全没问题,声明了require还能在compile阶段得到angular的保护。slides要求其子元素必须用slide-item进行一次(几乎是透明的)包装,换来的是完全的动态绑定,也可以接受。与此同时,每一个slide-item只会被link一次,还能避免$watch的重复绑定事件这类问题,在它被transclude的时候读取它的DOM内容也是可行的。
(不过我还是要吐槽一下ui-bootstrap的tabset实现,因为为了最终用户代码简洁,生成的最终DOM结构和组件树相差甚远,中间transclude来transclude去的,不过也是为了将就bootstrap)。
总之,对于构建一套组件而言:
子组件可以依赖父组件,父组件不要依赖子组件
宁愿依赖数据,不要依赖DOM
宁愿依赖结构,不要依赖内容
温馨提示:内容为网友见解,仅供参考
无其他回答

angularjs中指令中的compile参数是在什么时候运行的
在生成DOM后扫描并生成 angularJS肯定是在DOM节点树生成后开始管理节点的,生成后寻找ng-app标记,然后其下属所有节点均由ng来管理。使用compile可以改变原始的dom,在ng创建原始dom实例以及创建scope实例之前.ng-repeat就是一个最好的例子,它就在是compile函数阶段改变原始的dom生成多个原始dom节点,然后每个...

angularjs中怎么获取自定标签里面class里面的css属性
这是一个DOM操作。Angular不会帮助你获得DOM的某个属性。你需要使用的是DOM选择器,不管是原生的也好或者像jQuery这样的库也好。获取ID的目标地是为了操作DOM, Angular的设计思想不是这样的, 你应该用directive代替.directive的link函数已经把作用域,元素,属性数组注入到link函数调用的参数当中了.link(scope...

angularjs指令是什么意思
ng-app 指令初始化一个 AngularJS 应用程序。ng-init 指令初始化应用程序数据。ng-model 指令把元素值(比如输入域的值)绑定到应用程序。

在anjular中 function中的$scope和$rootscope有什么区别
使用 angular.element()返回的DOM对象,都会包含这2个方法,用来获取与之关联的scope和injector。由于每个模块的injector是唯一的,所以 angular.element().injector()直接返回元素所在模块的injector 。angular.element().scope()可以获取到当前元素的scope或父scope。如果当前元素有scope,则返回自己的scope;...

angular具有的指令类型
在组件模板中,我们可以使用内置的指令(如ngIf、ngFor),也可以创建自定义的指令。2. 属性指令(Attribute Directives):属性指令用于改变元素、组件或其他指令的行为和外观。例如,Angular内置的NgStyle和NgClass就是属性指令。我们也可以创建自定义属性指令,通过@Directive装饰器并指定selector为属性名来...

Angular之 ng-content 进阶
此时,父组件(parent)可能具有不同的状态,如parent.active表示组件是否处于选中状态。在这种情况下,子组件需要获取这种状态,从而涉及组件间通信。有多种处理方式,其中一种是利用Angular提供的ngTemplateOutlet指令和ngTemplateOutletContext提供context。ngTemplateOutlet用于渲染TemplateRef模板实例,并结合ng...

如何获取html元素id,通过angularjs
通过angularjs获取html元素的id的方法:angular.element("#element-id");这是一个DOM操作。Angular不会帮助获得DOM的某个属性。需要使用的是DOM选择器,不管是原生的也好或者像jQuery这样的库也好。获取ID的目标地是为了操作DOM, Angular的设计思想不是这样的, 应该用directive代替.directive的link函数已经...

在Angular开发中,为什么要选用ng
1.因为ng-click中解析的是AngularJs的表达式,而原生的click只是单纯的运行JavaScript的代码。2.ng-click配合其它的指令可以显示出其强大的能力。3还有一个问题就是作用域的问题,关于ng-click它的作用域在声明它的那个控制器的作用域内,而原生click的作用域一般情况下是全局范围的。

angular通过ng-bind-html绑定html内容
在构建个人博客时,遇到了一个需求,即在页面上动态展示包含HTML标签的内容。常规的ng-bind指令并不能满足这种要求。实际上,Angular提供了ng-bind-html来处理这种情况,它将值绑定为HTML元素的HTML属性,类似于jQuery中的text()和html()功能。然而,直接使用ng-bind-html可能会引发安全问题,因为Angular...

AngularJs进阶-作用域和控制器
每个Angular应用只有一个$rootscope,但可以拥有多个子作用域。当一些directive创建新的子作用域时,这些作用域会作为子作用域加入到父作用域中,形成与它们对应的DOM结构相似的树结构。当在HTML中对{{person}}求值时,AngularJS会首先检查当前元素关联的scope的person属性,如果没有找到,则会一直向上搜索父...

相似回答
大家正在搜