angular中关于自定义指令——repeat渲染完成后执行动作
业务中有时需要在异步获取数据并用ng-repeat遍历渲染完页面后执行某个操作,angular本身并没有提供监听ng-repeat渲染完成的指令,所以需要自己动手写。有经验的同学都应该知道,在ng-repeat模板实例内部会暴露出一些特殊属性$index/$first/$middle/$last/$odd/$even,$index会随着每次遍历(从0开始)递增,当遍历到最后一个时,$last的值为true,so,通过判断$last的值来监听ng-repeat的执行状态,怎么在遍历过程中拿到$last的值:自定义指令
小实例,我只写了最重要的部分

- //要循环的数据
- $scope.data = [
- {
- str: 'a'
- },
- {
- str: 'b'
- },
- {
- str: 'c'
- }
- ]
- //自定义指令repeatFinish
- app.directive('repeatFinish',function(){
- return {
- link: function(scope,element,attr){
- console.log(scope.$index)
- if(scope.$last == true){
- console.log('ng-repeat执行完毕')
- }
- }
- }
- })
- <div id="box">
- <span ng-repeat="item in data" repeat-finish>{{item.str}}</span>
- </div>

打开控制台,会打印出0,1,2,当$index = 2点时候,$last值为true,ng-repeat渲染完毕
so easy!
当然指令最好是能够复用,在这个指令内写具体的业务逻辑不利于复用,可以通过给指令指定一个处理函数renderFinish
- <div id="box">
- <span ng-repeat="item in data" repeat-finish="renderFinish()">{{item.str}}</span>
- </div>
再通过指令的attr参数获取这个处理函数

- app.directive('repeatFinish',function(){
- return {
- link: function(scope,element,attr){
- console.log(scope.$index)
- if(scope.$last == true){
- console.log('ng-repeat执行完毕')
- scope.$eval( attr.repeatFinish )
- }
- }
- }
- })
- //controller里对应的处理函数
- $scope.renderFinish = function(){
- console.log('渲染完之后的操作')
- }

attr获取到的属性只是一个字符串表达式,$scope.$eval方法是专门执行AngularJS表达式的,通过它处理函数得以执行,这样,指令用在不同的地方,可传递不同的处理函数。
有些业务比较复杂,可能ng-repeat渲染完成之后,需要执行多个操作并且这多个操作有多个前端完成,需要用到angular的事件,在repeatFinish指令的link函数内触发一个事件,各位前端同学监听该事件完成各自的操作

- app.directive('repeatFinish',function(){
- return {
- link: function(scope,element,attr){
- console.log(scope.$index)
- if(scope.$last == true){
- console.log('ng-repeat执行完毕')
- //向父控制器传递事件
- scope.$emit('to-parent');
- //向子控制器传递事件
- scope.$broadcast('to-child');
- }
- }
- }
- })
- //父控制器中监听事件
- $scope.$on('to-parent',function(){
- //父控制器执行操作
- })
- //子控制器中监听事件
- $scope.$on('to-child',function(){
- //子控制器执行操作
- })

如何在当前控制器下监听到该事件呢?angular没有向当前控制器传递事件的方法,可以先向父(子)控制器传递事件,父(子)控制器监听到事件后反过来向子(父)控制器传递事件。
补充:IE8可以直接在元素上用指令ng-if="$last && renderFinish()",当然IE8+也可以这样用
一句话总结:指令是angular的核心功能之一,用好了事半功倍,监听ng-repeat执行状态仅仅是它功能的冰山一角吧
补充2:然后我在使用的时候发现一个问题。这个问题依然是延时回调引起的,这不同于$http的异步问题,它不是异步,仅仅是延时问题。
我实用fbug断点调试发现,原来所谓的渲染完毕,其实并没有真正把数据填上,而是dom的渲染完毕,数据要等所有的dom渲染完毕之后对号入座。
可能有点抽象,直接上图。
看效果,
- $('.mybox-content').scrollTop( $('.mybox-content')[0].scrollHeight );
我使用scrollTop来对滚动条进行定位,原本应该是直接到最底部的,打印出来相应数据进行计算也是没有问题的,可是还是出现了这种情况,而且随着数据的增加,下面没滚动上去的也相应增加。
我就很苦恼,思考了很久很久,终于想通问题关键。
关键点就在于多出来的那部分,那么为什么多呢?是不是每一条的高度计算错误?这么想来,就对了,当聊天文本是多行的时候,就比默认的单行高度高出了一部分,而随着聊天记录的增加,多出来的这部分就随之增加。
这么看来就凸显出上面的问题了——渲染并没有真正完成。于是我打开断点,如下:
从图中我们可以看到,2 部分是渲染完成后进行的二次处理,处理完进入 3 ——滚动条置底。然而马上就要执行 3 的时候 2 部分却只有dom,没有相应的真实数据。而就像上面所说的,真实数据填入后条目的高度可能会变高,这就导致了滚动条不能置底。
问题明白了,解决办法就简单了。
- setTimeout(function(){
- $('.mybox-content').scrollTop( $('.mybox-content‘)[0].scrollHeight );
- }, 1);
只需要把代码放到一个延时器中就可以了,延时时间,1ms。。。。
angular中关于自定义指令——repeat渲染完成后执行动作的更多相关文章
- angular指令监听ng-repeat渲染完成后执行自定义事件方法
今天工作中遇到需要用到ng-repeat遍历渲染完后执行某个操作,angular本身并没有提供监听ng-repeat渲染完成的指令,所以需要自己创建自定义指令. 在ng-repeat模板实例内部会暴露 ...
- 在vue中创建自定义指令
原文:https://dev.to/ratracegrad/creating-custom-directives-in-vue-58hh 翻译:心上有杨 指令是带有 v- 前缀的特殊属性.指令的作用是 ...
- angular自定义指令 repeat 循环结束事件;limitTo限制循环长度、限定开始位置
1.获取repeat循环结束: 自定义指令: .directive('repeatFinish', function () { return { link: function (scope, elem ...
- 利用angular指令监听ng-repeat渲染完成后执行脚本
业务中有时需要在异步获取数据并用ng-repeat遍历渲染完页面后执行某个操作,angular本身并没有提供监听ng-repeat渲染完成的指令,所以需要自己动手写.有经验的同学都应该知道,在ng-r ...
- Angular.js之自定义指令学习笔记
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- 在Vue中通过自定义指令获取元素
vue.js 是数据绑定的框架,大部分情况下我们都不需要直接操作 DOM Element,但在某些时候,我们还是有获取DOM Element的需求的: 在 vue.js 中,获取某个DOM Eleme ...
- Vue2自定义指令改变DOM值后未刷新data中绑定属性的值
标签(空格分隔): Vue 自定义指令用于过滤输入框,只允许输入数字: Vue.directive('numberOnly', { bind: function (el, binding) { el. ...
- angular5中的自定义指令(属性指令)
属性型指令用于改变一个 DOM 元素的外观或行为. 在 Angular 中有三种类型的指令: 组件 — 拥有模板的指令 结构型指令 — 通过添加和移除 DOM 元素改变 DOM 布局的指令 属性型指令 ...
- angular中的ng-bind-html指令和$sce服务
angular js的强大之处之一就是他的数据双向绑定这一牛B功能,我们会常常用到的两个东西就是ng-bind和针对form的ng-model.但在我们的项目当中会遇到这样的情况,后台返回的数据中带有 ...
随机推荐
- pathForResource获取资源为nil的原因
利用NSbundle获取 资源文件的时候,如果是自己添加的文件,获取的时候纵使返回nil的解决办法.原因是因为该文件没有添加到资源文件中,只要在添加文件的时候选择添加到 Create Folder R ...
- WINDOWS-基础:_T
_T("")是一个宏,定义于tchar.h下. #define __T(x) L ## x #define _T(x) __T(x) 作用 他的作用是让你的程序支持Unicode编 ...
- selenium-浏览器操作方法
前戏 浏览器都有哪些方法呢?最大化,设置浏览器窗口的大小,刷新,前进,后退等等,让我们来一一介绍 获取网站titie from selenium import webdriver from time ...
- cmake 指定输出目录
$ mkdir ~/cpp-netlib-build $ cd ~/cpp-netlib-build $ cmake -DCMAKE_BUILD_TYPE=Debug \ > -DCMAKE_C ...
- PAT (Basic Level) Practise (中文)-1035. 插入与归并(25)
PAT (Basic Level) Practise (中文)-1035. 插入与归并(25) http://www.patest.cn/contests/pat-b-practise/1035 ...
- CS193p Lecture 8 - Protocols, Blocks and Animation
一.协议(Protocols) 1. 声明协议 @protocol Foo <Xyzzy, NSObject> // ... @optinal // @required //... @en ...
- Fortran学习记录3(选择语句)
流程控制语句 if的基本用法 if-else语句块 多重判断if-elseif语句 if语句嵌套 Select case语句 Goto语句 PAUSE CONTINUE STOP 流程控制语句 if的 ...
- 初涉倍增&&LCA【在更】
一种特殊的枚举算法 什么是倍增 顾名思义,即每一次翻倍增加.那么,这样我们就有了一种$O(logn)$阶的方法处理枚举方面的问题了. 参考:[白话系列]倍增算法 一些题目 [倍增]luoguP1613 ...
- (63)zabbix low-level discover zabbix批量部署必备
1. 概述 <zabbix发现配置>server通过配置好的规则,自动添加host.group.template <zabbix Active agent自动注册>与disco ...
- UNIX环境C语言进程通信
一.信号管理 1.函数signal signal函数是UNIX系统信号机制最简单的接口 #include <signal.h> typedef void (*sighandler_t)(i ...