带有 ng-repeat 的 Angular JS 指令无法遍历子元素
Angular JS directives with ng-repeat failing to loop through child elements
我正在使用AngularJS开发一个小解决方案(我是新手),我正在尝试使用<dl> <dt> <dd>
标签创建手风琴效果。我已经定义了一个ng-repeat
,用于从 .json 文件在 dl 中创建 dt 和 dd,并且效果很好。
当我想通过指令添加一些功能时,我的问题就出现了,所以我可以通过单击 <dt>
元素来显示/隐藏<dd>
元素。我的指令的代码似乎不起作用,因为它并没有真正做我期望的事情 - 它什么也没做。也许指令试图在ng-repeat
完成其过程之前添加功能?但为此,我添加了$timeout变量。
整体解决方案:http://codepen.io/valecarlos/pen/PNdpeZ
指令代码:
app.directive('accordion', function($timeout){
return{
restrict: 'E',
transclude: true,
replace: true,
scope: {},
template: '<dl ng-transclude></dl>',
link: function(scope,element){
$timeout(function() {
console.log(element)
console.log(element.children().length);//this gives me 0
console.log("im here" + element)
element.children().find('dd').css('display','none');
element.find('dt').on('click', function(event){
element.children().find("dd").css('display', 'none')
var ddToOpen = angular.element(event.target).next();
ddToOpen.css('display','block');
});
});
}
};
});
.HTML:
<accordion>
<dt ng-repeat-start="article in articles">
//my content
</dt>
<dd ng-repeat-end="">
//my content
</dd>
<accordion>
注意:我尝试使用 jquery 和 AngularJS 实现此手风琴,但当我单击 dt
元素时没有任何反应
问题是(如笔中所示)您正在异步加载数据,而不是等待承诺解决。这就是我的意思:
$http.get('http://www.carlosvalencia.co/news_mock.json').success(function(data) {
//$timeout and the DOM stuff will be long gone when we get here :(
$scope.articles = data;
});
当然,使用 $timeout
会等到 angular 完成模板渲染工作,但它不会等待您的数据加载。当 DOM 操作完成时,没有要列出的文章,因此没有要查找的元素。
现在你需要做的是以某种方式告诉你的指令推迟做它的事情,直到数据准备好。我没有一个明确的适合所有人的解决方案来做到这一点。Angular 提供了几种用于组件之间通信的方法,它们在某些目的上都运行良好,但可能对其他目的不利。例如,这里最简单的方法可能是使用 scope.$broadcast 告诉指令一切准备就绪。
但是,这可能不是最好的解决方案,因为事件可能会在组件之间创建非常微妙的依赖关系。相反,我会明确要求手风琴指令中的承诺,以便父控制器可以指示我们何时准备好滚动。所以我会添加
scope: {
promise: '&?' //Ask for an optional promise getter from the parent template
}
template: '<dl ng-transclude></dl>',
link: function(scope,element){
//We'll either wait for the given promise or default to a resolved promise
var promise = scope.promise ? scope.promise() : $q.resolve();
//Wait for both that promise AND the additional $timeout before doing DOM stuff
promise.then($timeout).then(function() {
console.log(element)
console.log(element.children().length);//shouldn't be 0 anymore
//... the DOM stuff
});
}
现在,我们只需要传递父控制器的$http承诺。
$scope.promise = $http.get('http://www.carlosvalencia.co/news_mock.json').success(function(data) {
$scope.articles = data;
});
并在使用手风琴指令时使用它
<accordion promise="promise" >
<dt ng-repeat-start="article in articles">
...
这是一个可行的解决方案。(请注意,我不得不用其他方法替换$http
方法进行测试,您应该可以使用$http)
更新:您还需要将所有element.children().find(selector)
调用替换为element.find(selector)
才能找到元素。我已经更新了笔以覆盖它。
- 遍历类元素数组,并在jquery中选择同级元素
- Jquery遍历表元素
- JS.循环遍历多维数组,以计数元素在每列中的出现次数
- 如何使用 document.querySelectorAll 遍历选定的元素
- 当知道同一hiearch中至少有一个元素时,遍历到元素.结构使用jquery
- 循环遍历元素jquery选择器
- 遍历元素,更改z索引,Javascript
- Angularjs ,a 在 foreach 中是未定义的,用类循环遍历元素
- 循环遍历元素并根据链接属性进行更改
- 遍历元素列表并隐藏它们
- 遍历元素,向每个元素添加click事件
- 如何使用for循环循环遍历元素列表并动态设置元素样式
- 遍历元素并添加索引号
- jQuery中循环遍历元素和显示/隐藏的函数
- 遍历元素列表并根据内部文本删除元素上的游标样式
- 试图循环遍历元素为object的数组
- icanhaz/胡子循环(遍历元素)js错误
- Javascript循环遍历元素并添加到表中
- 用户脚本,遍历元素和测试属性
- jQuery each()函数不循环遍历元素