首页 >> 大全

angularjs执行ng-repeat判断完成状态,生成可复用性自定义指令

2023-09-01 大全 28 作者:考证青年

更新 问题背景

今天整体把页面js重写过了下,发现了新的问题。

ng-如做了ng-if判断做过滤显示,那渲染完后就拿不到scope.$last为true的情况,此时使用下面on--方法在调用则不会触发

测试后发现ng-if并非完全不可触发

(遍历json对象共5个元素,属性index为0的2个,为1的3个,元素的index排列为0,1,0,1,1,以下为模拟数据)

allmenu = {"aa":{"index":0},"bb":{"index":1},"cc":{"index":0},"dd":{"index":1},"ff":{"index":1}
}

最初样例代码(失败无法触发)

<ul><li ng-repeat='x in allMenu' ng-bind="x.name" ng-if="x.index==0" on-finish-render="afterTopMenuRepeat"></li><div class='clear'></div>
</ul>

上面代码因为使用了ng-if而无法触发完成状态,scope.$last!=true 。

而如不使用ng-if,则能正常使用,如下图。

这里猜测是:

一是scope.$last获取的是队列里的最后一个元素下标状态;(正确)二是必须全部所有元素被数据填充完才能获取到的状态。(正确)

猜测2很好论证,只有不设定ng-if即可自证,所以仅验证猜测1。

之前ng-if条件x.index == 0拿到了位置1,3的数据,现在设定x.index==1,将会拿到位置2,4,5(5是最后一个元素)的数据,并且成功触发完成状态。如下图,说明

指令实现_

解决办法

目前我的代码不需要很复杂的逻辑,所以采用了ng-show来代替ng-if,页面效果一致,scope.$last也能正常拿到。

-----------------------------------------------------------我是一条华丽又低调的更新分割线------------------------

先上代码

html

//调用监听事件afterRightEditRepeat,注意不要写成afterRightEditRepeat()调用形式
<div ng-repeat="x in menu" on-finish-render="afterRightEditRepeat">
....
</div>

js自定义指令部分

//onFinishRender对应属性on-finish-render
app.directive('onFinishRender', ['$timeout', afterNgRepeatRender]).controller();//调用下面这个方法判	
function afterNgRepeatRender($timeout){return {restrict:'A',link:function(scope,ele,attr){if(scope.$last == true){ //scope.$last渲染完成后为true$timeout(function(){scope.$emit(attr.onFinishRender);//scope.$emit('函数声明名'),接收一个字符串//如果div的on-finish-render属性值写成了函数调用的形式,则$emit会调用失败},10)}}}
}

app.()内定义事件监听

//attr.onFinishRender可以让onFinishRender指令重复使用
$scope.$on('afterRightEditRepeat', function(event){console.log('右边菜单内容填充完成');		
})//只需要在给属性赋值时根据后续逻辑匹配不同的监听事件即可
$scope.$on('afterTopMenuRepeat', function(event){console.log('左边顶级菜单加载完成');
})

解释

原先是想直接在 内部使用获取ng-的元素,结果拿到了,然后又使用angul.获取元素,报错

原因是应优先加载

_指令实现

正确加载顺序如图

但结果仍是。

继续探索…

做了两种考虑,都是关于页面加载的

一是先想到的可能是.,$().ready((){})的问题。

代码包裹在.里后,页面刷新提示了控制器app.(aa())未加载的错误如下。

尝试简化写法app.()也是直接报错,说明不是代码以及调用顺序问题。而觉得app.()在.里面这种写法也许就是存在错误的。

想想其实很合理,元素要被渲染后后才能实现DOM树完全加载(执行$.ready()),编译阶段需要控制器提供数据的,app.最好直接写在页面(加载)里面。

二是考虑到渲染的问题,用alert()走了一下页面,发现好几个地方的alert()弹出来的时候页面还是空白,说明数据都没加载出来,元素自然也没有出来,所以拿了个空。

于是去搜元素渲染的相关解决办法,百度还算顺利。

获取了两个知识

scope.$last 表示渲染完的状态,是最后一条则为true
scope.$emit() 表示触发事件

就是记住在自定义指令写成元素属性后进行赋值的时候,值不要写成事件调用的形式,要是个字符串,scope.$emit()才能调用成功。

关于我们

最火推荐

小编推荐

联系我们


版权声明:本站内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 88@qq.com 举报,一经查实,本站将立刻删除。备案号:桂ICP备2021009421号
Powered By Z-BlogPHP.
复制成功
微信号:
我知道了