浅谈Angular中ngModel的$render


Posted in Javascript onOctober 24, 2016

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

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

Input里面模型的值:{{vm.modelTest}}
<input type="text" ng-model="vm.modelTest" model-render>
.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);
        }) 
      }
    }
  })

我们分几种情况分析

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

浅谈Angular中ngModel的$render

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

结果是这样的

浅谈Angular中ngModel的$render

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

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

浅谈Angular中ngModel的$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是不同的)

浅谈Angular中ngModel的$render

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

浅谈Angular中ngModel的$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;
 });
}];

以上就是小编为大家带来的浅谈Angular中ngModel的$render全部内容了,希望大家多多支持三水点靠木~

Javascript 相关文章推荐
js 刷新页面的代码小结 推荐
Apr 02 Javascript
jQuery:节点(插入,复制,替换,删除)操作
Mar 04 Javascript
jquery $.fn $.fx是什么意思有什么用
Nov 04 Javascript
wap浏览自动跳转到wap页面的js代码
May 17 Javascript
8 行 Node.js 代码实现代理服务器
Dec 05 Javascript
JS实现改变HTML上文字颜色和内容的方法
Dec 30 Javascript
Linux使用Node.js建立访问静态网页的服务实例详解
Mar 21 Javascript
JavaScript中闭包的详解
Apr 01 Javascript
详解Node.js项目APM监控之New Relic
May 12 Javascript
对vue里函数的调用顺序介绍
Mar 17 Javascript
Postman参数化实现过程及原理解析
Aug 13 Javascript
JS删除对象中某一属性案例详解
Sep 08 Javascript
Javascript vue.js表格分页,ajax异步加载数据
Oct 24 #Javascript
H5移动端适配 Flexible方案
Oct 24 #Javascript
javascript的document中的动态添加标签实现方法
Oct 24 #Javascript
Ajax+FormData+javascript实现无刷新表单信息提交
Oct 24 #Javascript
利用JS实现点击按钮后图片自动切换的简单方法
Oct 24 #Javascript
express文件上传中间件Multer详解
Oct 24 #Javascript
用js实现博客打赏功能
Oct 24 #Javascript
You might like
让php处理图片变得简单 基于gb库的图片处理类附实例代码下载
2011/05/17 PHP
destoon实现底部添加你是第几位访问者的方法
2014/07/15 PHP
php解析http获取的json字符串变量总是空白null
2015/03/02 PHP
php处理抢购类功能的高并发请求
2018/02/08 PHP
常见JS效果之图片减速度滚动实现代码
2011/12/08 Javascript
jquery放大镜效果超漂亮噢
2013/11/15 Javascript
js监听滚动条滚动事件使得某个标签内容始终位于同一位置
2014/01/24 Javascript
vue子父组件通信的实现代码
2017/07/09 Javascript
Vue编写多地区选择组件
2017/08/21 Javascript
vue、react等单页面项目应该这样子部署到服务器
2018/01/03 Javascript
ES6关于Promise的用法详解
2018/05/07 Javascript
jQuery内容过滤选择器与子元素过滤选择器用法实例分析
2019/02/20 jQuery
一文快速详解前端框架 Vue 最强大的功能
2019/05/21 Javascript
Vue商品控件与购物车联动效果的实例代码
2019/07/21 Javascript
使用原生JS实现火锅点餐小程序(面向对象思想)
2019/12/10 Javascript
easyUI使用分页过滤器对数据进行分页操作实例分析
2020/06/01 Javascript
jQuery实现穿梭框效果
2021/01/19 jQuery
[03:36]2014DOTA2 TI小组赛综述 八强诞生进军钥匙球馆
2014/07/15 DOTA
Python实现的序列化和反序列化二叉树算法示例
2019/03/02 Python
python 画二维、三维点之间的线段实现方法
2019/07/07 Python
CSS3实现王者匹配时的粒子动画效果
2019/04/12 HTML / CSS
HTML5新增form控件和表单属性实例代码详解
2019/05/15 HTML / CSS
英国知名化妆品网站:Revolution Beauty(原TAM Beauty)
2018/02/28 全球购物
澳大利亚天然护肤品、化妆品和健康产品一站式商店:Nourished Life
2018/12/02 全球购物
ZINVO手表官网:男士和女士手表
2019/03/10 全球购物
英国发展最快的在线超市之一:Click Marketplace
2021/02/15 全球购物
电子商务个人职业生涯规划范文
2014/02/12 职场文书
《老王》教学反思
2014/02/23 职场文书
工作骂脏话检讨书
2014/10/05 职场文书
离婚协议书范本
2015/01/26 职场文书
技术负责人岗位职责
2015/02/10 职场文书
龙猫观后感
2015/06/09 职场文书
网络研修随笔感言
2015/11/18 职场文书
人生一定要学会的三样东西:放下、忘记、珍惜
2019/08/21 职场文书
PHP判断是否是json字符串
2021/04/01 PHP
Python中request的基本使用解决乱码问题
2022/04/12 Python