在我开始着手ngModel的领域时候,有一个问题很令我纠结,那就是$render()到底是做什么的呢?查了很多资料都只是简单的描述一下,这就令我很纠结了,终于在一个阳光明媚的晚上,我终于解决了这个大问题

  那么这个$render方法到底是干什么的呢?他的用处就是在$viewValue改变的时候可以重新绑定model数据,但是我们要注意一点($viewValue和DOM节点的value是不同的),我觉得他们的区别有点类似setTimeout和$timeout的区别,但是又不太一样。ps:其实modelValue和绑定的数据也可以不同

Input里面模型的值:{{vm.modelTest}}
<input type="text" ng-model="vm.modelTest" model-render>

View Code

.directive('modelRender', function () {return {require: 'ngModel',link: function (scope, iElm, iAttrs, ngModelCtrl) {iElm.on('mouseenter', function () {//尝试注释iElm.val(1);console.log(ngModelCtrl);//尝试注释ngModelCtrl.$setViewValue(11);console.log(ngModelCtrl);//尝试注释
                    ngModelCtrl.$render();console.log(ngModelCtrl);}) }}})

View Code

我们分几种情况分析

这是鼠标没有经过指令的时候的样子

  1.当我们使用js原生方法设置input的val值的时候,并且不执行$render函数,我们可以看到input里面的model值是没有变化的,但是input的的value是变成了1,而且我们看到不仅model值没有变化,ngModel的$viewValue和$modelValue同样也没有变化。我们可以得出结论 (input的value值不一定等于$viewValue)

   结果是这样的

-----------------------------------------------------------------------------------------------------------------------  

  然后,我们尝试在执行js原生改变value值之后,执行$render函数是个什么样的状况,

  

  看完上面的实验之后我们发现input的value值并没有发生变化,也就是说js原生改变input的value值是无效的,那么在这里我们就可以看到$render的功能了。

  我们可以大胆的预计$render的功能跟$apply的功能是一致的,我们在上一章讲过,$apply是以viewValue为主,让modelValue变成viewValue,也就是modelValue -> viewValue,那么$render是不是以modelValue为主,让viewValue->modelValue呢? 

-------------------------------------------------------------------------------------------------------------------------

  2.接下来我们尝试,使用ng原生改变 也就是说$setviewValue,是如何表现的呢?

   现在我们注释掉js原生改变value的方法,而去使用$setViewValue,并且不执行$render函数,直接上结果,我们看到,执行完$setViewValue之后,无论是viewValue和modelValue都是已经同步了,但是input里面的值却依然是test,在这里我们再次验证了那个说法($viewValue和DOM节点的value是不同的)

  现在我们在$setViewValue之后使用,$render()看看是什么效果,

 

  大家发现了吧,$render的功能和$apply的功能极为相似,但是是不是很多人在讲$render的时候,都会说model同步到view,我觉得这个说法不太对,我测试过在click事件用非常规手段改变controller中model的值,发现就算controller的值已经改变了,但是ngModel的值无论是viewValue还是modelValue都没有变化,然后尝试用$modelValue的属性强行改变$modelValue,结果还是没作用。我们下面来看看$render的源码  

ctrl.$render = function() {element.val(ctrl.$isEmpty(ctrl.$viewValue) ? '' : ctrl.$viewValue);};

  这是其中一个,$render在不同的指令下的代码都不太一样,但是其作用基本一致,但是从这里我们就可以看出$render的到底在干什么事了。那么$render什么时候触发呢?其实看你自己想什么时候调用它,你可以覆盖他的方法,重写,在$watch也好,$viewChange也好。默认的触发事件一些特别input的value改变的时候例如单选,还有rollbackView()的时候

  另外一个真正体现$render执行事件的源代码在这里,里面我写了注释,大家应该都能懂  

  

$scope.$watch(function ngModelWatch() {//解析ngModel的表达式,获取内容var modelValue = ngModelGet($scope);// if scope model value and ngModel value are out of sync// TODO(perf): why not move this to the action fn?//判断表达式的值是否跟modelValue一致if (modelValue !== ctrl.$modelValue &&// checks for NaN is needed to allow setting the model to NaN when there's an asyncValidator(ctrl.$modelValue === ctrl.$modelValue || modelValue === modelValue)) {//更新modelValue的值ctrl.$modelValue = ctrl.$$rawModelValue = modelValue;parserValid = undefined;//获取管道信息var formatters = ctrl.$formatters,idx = formatters.length;var viewValue = modelValue;while (idx--) {viewValue = formatters[idx](viewValue);}//如果viewValue和ModelValue不一致if (ctrl.$viewValue !== viewValue) {ctrl.$viewValue = ctrl.$$lastCommittedViewValue = viewValue;ctrl.$render();ctrl.$$runValidators(modelValue, viewValue, noop);}}//返回解析的表达式return modelValue;});
}];

  好了,$render就已经讲完了,这是作者的原创帖,如转载 请注明,最后贴段代码感受下  

转载于:https://www.cnblogs.com/HeJason/p/5486991.html

Angular中ngModel的$render的详解相关推荐

  1. angular读取html文件路径,angular中关于路径问题的详解

    我们在写项目时会遇到启动页调到引导页,引导页再调到首页, 那我们在用angular框架写这种东西的时候如果我们不细心的话就会遇到问题, 比如说找不到引导页的图片等等. 那我们怎么解决这个问题呢? 首先 ...

  2. php中this的使用技巧,JavaScript中this关键字使用方法详解

    JavaScript中this关键字使用方法详解 在面向对象编程语言中,对于this关键字我们是非常熟悉的.比如C++.C#和Java等都提供了这个关键字,虽然在开始学习的时候觉得比较难,但只要理解了 ...

  3. django批量修改table_python中Django视图(view)的详解(附示例)

    本篇文章给大家带来的内容是关于python中Django视图(view)的详解(附示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 一个视图函数(类),简称视图,是一个简单的Py ...

  4. Unity Shader中各部分定义内容详解

    Unity Shader中各部分定义内容详解 样板 Shader "Practice/Unlit/SimpleUnlit" {Properties{_MainTex (" ...

  5. python find的使用方法_Python中的rfind()方法使用详解

    Python中的rfind()方法使用详解 rfind()方法返回所在子str 被找到的最后一个索引,或者-1,如果没有这样的索引不存在,可选择限制搜索字符串string[beg:end]. 语法 以 ...

  6. Linux中/proc目录下文件详解

    Linux中/proc目录下文件详解(一) 声明:可以自由转载本文,但请务必保留本文的完整性. 作者:张子坚 email:zhangzijian@163.com 说明:本文所涉及示例均在fedora ...

  7. python创建列向量_关于Numpy中的行向量和列向量详解

    关于Numpy中的行向量和列向量详解 行向量 方式1 import numpy as np b=np.array([1,2,3]).reshape((1,-1)) print(b,b.shape) 结 ...

  8. jQuery中getJSON跨域原理详解

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp28 jQuery中getJSON跨域原理详解 前几天我再开发一个叫 河蟹工 ...

  9. java mod %区别_Java中 % 与Math.floorMod() 区别详解

    %为取余(rem),Math.floorMod()为取模(mod) 取余取模有什么区别呢? 对于整型数a,b来说,取模运算或者取余运算的方法都是: 1.求 整数商: c = a/b; 2.计算模或者余 ...

最新文章

  1. 使用JUnit进行单元测试
  2. python实现文件搜索_python实现搜索指定目录下文件及文件内搜索指定关键词的方法...
  3. 监管发文:规范大学生群体消费贷款,避免陷入消费贷款陷阱
  4. 易优cms后台RCE以及任意文件上传漏洞
  5. html css 画五角星,纯 CSS3 绘制图形(心形、五角星、六边形等)
  6. Struts2自己定义拦截器实例—登陆权限验证
  7. 关于ElasticSearch处理过滤条件
  8. ScrollView 里面捕获OnTouchMove事件
  9. androidstudio jni开发_高考失利落榜,7年Android开发现已年薪60w,我的逆袭之路想说给你听...
  10. TCP/IP笔记 三.运输层(3)——TCP超时重传算法
  11. c# listView
  12. 华三服务器bios中查看硬盘,H3C服务器升级BIOS
  13. android svn上传代码,Android应用开发之项目上传svn(Android Studio)
  14. linux中telnet命令安装包,linux的telnet命令安装
  15. 如何打开asm文件(学习汇编语言)
  16. 从软件测试培训班出来之后找工作的经历,教会了我这五件事...
  17. esp分区引导修复失败_gpt分区怎么修复引导?uefi+gpt分区修复esp引导教程
  18. 纵行科技联合Kinéis等欧洲企业,开发ZETA星地融合低功耗物联网芯片
  19. 被高通裁员两次,清华毕业华裔工程师跳楼身亡!中年IT男,为何这么难?
  20. 在Linux下掌握arm和操作系统(0)--开篇闲聊

热门文章

  1. 建站手册-语义网:语义网
  2. STL 二分查找 upper_bound和lower_bound用法
  3. Java——super的使用
  4. ecshop 去版权
  5. 安卓自动化测试(一)
  6. 4、线程范围内的数据共享之ThreadLocal
  7. Linux新手上路命令
  8. iOS学习笔记37 时间和日期计算
  9. jQuery的ajax()、post()方法提交数组,参数[] 问题
  10. 在gem5的full system下运行 x86编译的测试程序 running gem5 on ubuntu in full system mode in x86...