博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ngModel使用说明小demo
阅读量:7017 次
发布时间:2019-06-28

本文共 4593 字,大约阅读时间需要 15 分钟。

第一个点,要了解下:

  • DOM value

  • $viewValue

  • $modelValue

  • scope上挂载的属性的值

一般有2个流程:

  1. $viewValue -->> $modelValue -->> scope 上挂载的属性的值

  2. scope上挂载的属性的值 -->> $modelValue -->> $viewValue

ngModel常用的场景就是如果你使用第三方的插件例如时间插件,每次选择时间后都是更新DOM value的值,这个时候DOM value上的值事实上是你需要绑定到scope属性上的值。那么这个时候就需要ngModelController

在第一个流程当中,例如我加载了一个时间插件:

html:        

选择的时间为: {

{date.from}}

js: angular.module('demoApp', []).controller('demoCtrl', function($scope) { $scope.date = { from: '' }; $scope.$watch('date.from', function(val) { console.log(val); }); }) .directive('testDirective', ['$timeout', function($timeout) { return { restrict: 'EA', require: '?ngModel', link: function(scope, ele, attrs, ngModel) { template: '', link: function (scope, ele, attr, ngModel) { var picker = new Pikaday({ field: $('#pikadayTimerPicker')[0], firstDay: 0, yearRange: [2000, 2020], format: 'YYYY-MM-DD', hours24format : false, showTime : true, splitTimeView : true, showSeconds : true, minutesStep : 5, i18n: { previousMonth : '上月', nextMonth : '下月', months : ['一月','二月','三月','四月','五月','六月','七月','八月','九月','十月','十一月','十二月'], weekdays : ['周日','周一','周二','周三','周四','周五','周六'], weekdaysShort : ['日','一','二','三','四','五','六'] }, onSelect: function () { if(!ngModel) return; //如果ngModel不存在 ngModel.$setViewValue(this._d); } }); } } } })

onSelect回调事件里面,调用了ngModel.$setViewValue方法,它的作用就是使DOM value -->> $viewValue -->> $modelValue -->> scope上绑定的属性.

第二个流程当中,比如你需要初始化一个时间,这个时间可能是从你后台调过来的,或者是获取的本地的时间.那么你首先要绑定scope上的属性值,但是这个时候在时间插件上面显示的时间并不是scope上绑定的属性值,这个时候就需要$render方法了:

$scope.data.from = $filter(new Date().valueOf())('YYYY-MM-DD hh:mm:ss');    xxxxx        var picker = new Picker({ xxxx });                //这个地方调用        ngModel.$render = function() {            $('#pikadayTimerPicker').val(ngModel.$viewValue);        }    xxxxx

这里执行的流程就是:

scope上绑定的属性值发生变化 -->> $modelValue -->> $viewValue -->> 调用$('#pikadayTimerPicker').val(ngModel.$viewValue)去更新DOM value.

在2个流程当中还应当注意一些地方:

第一个流程当中会经过$parsers, $validators2个管道。

第二个流程当中会经过$formatters,$render, $validators 3个管道。

关于$parses, $formatters , $validators 3个管道的用法会在下一篇里面讲。

这里着重讲一下源码里的$render方法(文档23189行),

ctrl.$render = function() {    // Workaround for Firefox validation #12102.    var value = ctrl.$isEmpty(ctrl.$viewValue) ? '' : ctrl.$viewValue;    if (element.val() !== value) {      element.val(value);    }  };

这里就是首先判断$viewValue是否为空,然后再判断当前元素的DOM Value$viewValue是否一样,再选择是否更新视图。

另外就是需要注意的一个地方(文档26947行):

$scope.$watch(function ngModelWatch() {    var modelValue = ngModelGet($scope); //获取scope上绑定的ng-model的值        // if scope model value and ngModel value are out of sync    // TODO(perf): why not move this to the action fn?    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)    ) {      ctrl.$modelValue = ctrl.$$rawModelValue = modelValue;      parserValid = undefined;      var formatters = ctrl.$formatters,          idx = formatters.length;      var viewValue = modelValue;      while (idx--) {        viewValue = formatters[idx](viewValue);      }              if (ctrl.$viewValue !== viewValue) {        ctrl.$$updateEmptyClasses(viewValue);        ctrl.$viewValue = ctrl.$$lastCommittedViewValue = viewValue;        ctrl.$render();        ctrl.$$runValidators(modelValue, viewValue, noop);      }    }    return modelValue;  });

$render方法一般是当ng-model的值发生变化的时候就会触发:

  • 例如ng-model直接放在input,select标签内,那么ng会自动响应ng-model变化后,便会触发这个方法,来使Dom$scope上挂载的属性值保持相同.

  • 指令内部封装了input标签,但是ng-model是在指令外部的外部标签下时。一般需要通过event handler去调用ngModel.$setViewValue方法去时DOM Valuescope上挂载的属性值保持一致。具体的demo就如上例。

ngModel.$render方法是可以重新自定义的:

ngModel.$render = function() {        // scope上的属性值,$modelValue, $viewValue已经发生变化        // 利用这些值再次可以再次做相应的处理,然后更新DOM value    }

抽时间把关于ngModel再补上。睡觉。

参考资料:

转载地址:http://nezxl.baihongyu.com/

你可能感兴趣的文章
微渠道发展 BAE交通运输平台和java呼声,微信mysql数据库开发实例 --图文开发教程...
查看>>
LintCode: Count 1 in Binary
查看>>
【OC加强】NSDate的使用方法——日期时间在实际开发中比較有用
查看>>
SQL Server死锁总结(转载)
查看>>
iOS:步进UIStepper、滑动块UISlider、开关UISwitch的基本使用
查看>>
ubuntu安装deb,rpm安装包方法
查看>>
[Android Studio] Android Studio底边栏选项不见了,如何调出来
查看>>
Kali linux 2016.2(Rolling)里Metasploit连接(包括默认和自定义)的PostgreSQL数据库之后的切换到指定的工作空间...
查看>>
用jsmooth + inno生成exe并制作简单安装包
查看>>
关于spring-mvc.xml的mvc:resources元素浅析。
查看>>
Hadoop WordCount改进实现正确识别单词以及词频降序排序
查看>>
MVVM架构~knockoutjs实现简单的购物车
查看>>
ASP.NET图片上传方法总结
查看>>
【Github教程】史上最全github使用方法:github入门到精通
查看>>
一个根据列的范围分组汇总的Sql存储过程
查看>>
支点:技术选择的精髓
查看>>
swiper去除滑动设置
查看>>
Microsoft Enterprise Library 5.0 系列教程(十) Configuration Application Block
查看>>
Silverlight中的Slider控件
查看>>
Redis学习笔记~分布锁的使用
查看>>