我们知道ngModel是AngularJS中默认的一个Directive,用于数据的双向绑定。通常是这样使用的:

<input type="text" ng-model="customer.name" />

在控制器中大致这样:

$scope.customer ={
    name: ''
}

上一篇中,有关表格的Directive是这样使用的:

<table-helper datasource="customers" clumnmap="[{name: 'Name'}, {street: 'Street'}, {age: 'Age'}, {url: 'URL', hidden: true}]"></table-helper>

以上,datasource代表数据源,是否可以用ng-model替代呢?

比如写成这样:

<table-helper-with-ng-model ng-model="customers" columnmap="[{name:'Name'}...]">
</table-helper-with-ng-model>

可是,自定义的tableHelper这个Direcitve如何获取到ngModel中的值呢?

这就涉及到Direcitve之间的通讯了,就像在"AngularJS中Directive间交互实现合成"说的。

要解决的第一个问题是:如何拿到ngModel?

--使用require字段

  1. return {
  2. restrict: 'E',
  3. required: '?ngModel', //^ngModel本级或父级, ^^ngModel父级
  4. scope: {
  5. columnmap: '='
  6. },
  7. link: link,
  8. template: template
  9. }

要解决的第二个问题是:如何从ngModel这个Direcitve拿数据?

--使用ngModel.$modelValue

要解决的的第三个问题是:当ngModel值变化,如何告之外界并重新加载表格?

--大致有4种方法

  1. //1 观察某个属性的值
  2. attrs.$observe('ngModel', function(value){
  3. //监视变量的值
  4. scope.$watch(value, function(newValue){
  5. render();
  6. });
  7. });
  8.  
  9. //2 或者
  10. scope.$watch(attrs.ngModel, render);
  11.  
  12. //3 或者
  13. scope.$watch(function(){
  14. return ngModel.$modelValue;
  15. }, function(newValue){
  16. render();
  17. })
  18.  
  19. //4 或者
  20. ngModel.$render = function(){
  21. render();
  22. }

相对完整的代码如下:

  1. var tableHelperWithNgModel = function(){
  2.  
  3. var dataSource;
  4.  
  5. var template = '<div class="tableHelper"></div>';
  6.  
  7. var link = function(scope, element, attrs, ngModel){
  8.  
  9. ...
  10.  
  11. function render(){
  12. if(ngModel && ngModel.$modelValue.length){
  13. datasource = ngModel.$modelValue;
  14. table += tableStart;
  15. table += renderHeader();
  16. table += renderRows() + tableEnd;
  17. renderTable();
  18. }
  19. }
  20. };
  21.  
  22. return {
  23. restrict: 'E',
  24. required: '?ngModel', //^ngModel本级或父级, ^^ngModel父级
  25. scope: {
  26. columnmap: '='
  27. },
  28. link: link,
  29. template: template
  30. }
  31. }
  32.  
  33. angular.module('direcitveModule')
  34. .directive('tableHelperWithNgModel', tableHelperWithNgModel)
  35.  
  36. var tableHelperWithNgModel = function(){
  37.  
  38. var dataSource;
  39.  
  40. var template = '<div class="tableHelper"></div>';
  41.  
  42. var link = function(scope, element, attrs, ngModel){
  43.  
  44. //观察某个属性的值
  45. attrs.$observe('ngModel', function(value){
  46. //监视变量的值
  47. scope.$watch(value, function(newValue){
  48. render();
  49. });
  50. });
  51.  
  52. //或者
  53. scope.$watch(attrs.ngModel, render);
  54.  
  55. //或者
  56. scope.$watch(function(){
  57. return ngModel.$modelValue;
  58. }, function(newValue){
  59. render();
  60. })
  61.  
  62. //或者
  63. ngModel.$render = function(){
  64. render();
  65. }
  66.  
  67. function render(){
  68. if(ngModel && ngModel.$modelValue.length){
  69. datasource = ngModel.$modelValue;
  70. table += tableStart;
  71. table += renderHeader();
  72. table += renderRows() + tableEnd;
  73. renderTable();
  74. }
  75. }
  76. };
  77.  
  78. return {
  79. restrict: 'E',
  80. required: '?ngModel', //^ngModel本级或父级, ^^ngModel父级
  81. scope: {
  82. columnmap: '='
  83. },
  84. link: link,
  85. template: template
  86. }
  87. }
  88.  
  89. angular.module('direcitveModule')
  90. .directive('tableHelperWithNgModel', tableHelperWithNgModel)

自定义Directive使用ngModel的更多相关文章

  1. 理解AngularJS生命周期:利用ng-repeat动态解析自定义directive

    ng-repeat是AngularJS中一个非常重要和有意思的directive,常见的用法之一是将某种自定义directive和ng-repeat一起使用,循环地来渲染开发者所需要的组件.比如现在有 ...

  2. AngularJS自定义Directive

    (编辑完这篇之后,发现本篇内容应该属于AngularJS的进阶,内容有点多,有几个例子偷懒直接用了官方的Demo稍加了一些注释,敬请见谅). 前面一篇介绍了各种常用的AngularJS内建的Direc ...

  3. 关于angular 自定义directive

    关于angular 自定义directive的小结 首先我们创建一个名为"expander"的自定义directive指令: angular.module("myApp& ...

  4. AngularJs中,如何在父元素中调用子元素为自定义Directive中定义的函数?

    最近一段时间准备使用AngularJs中的自定义Directive重构一下代码. 在这里说明一下,把自定义控件封装成Directive并不一定是要复用,而是要让代码结构更加清晰.就好像你将一个长方法拆 ...

  5. AngularJS自定义Directive中link和controller的区别

    在AngularJS中,自定义Directive过程中,有时用link和controller都能实现相同的功能.那么,两者有什么区别呢? 使用link函数的Directive 页面大致是: <b ...

  6. AngularJS自定义Directive不一定返回对象

    AngularJS中,当需要自定义Directive时,通常返回一个对象,就像如下的写法: angular.module('modulename') .directive('myDirective', ...

  7. AngularJS自定义Directive初体验

    通常我们这样定义个module并随之定义一个controller. var app = angular.module('myApp', []); app.controller('CustomersCo ...

  8. AngularJs(Part 11)--自定义Directive

    先对自定义Directive有一个大体的映像 myModule.directive('myDirective',function(injectables){ var directiveDefiniti ...

  9. angularJs中自定义directive的数据交互

    首先放官方文档地址:https://docs.angularjs.org/guide/directive 就我对directive的粗浅理解,它一般用于独立Dom元素的封装,应用场合为控件重用和逻辑模 ...

随机推荐

  1. js实现星级评分效果(非常规5个li代码)

    1. 前言 此方案受到JS单行写一个评级组件启发,自己写了一个简单Demo. 功能有正常滑动,动态显示实心星星个数:当点击确认,则保持当前的实心星星个数:再移动时未点击,则离开后还是保持之前的状态. ...

  2. PYTHON-组合 封装 多态 property装饰器

    # 组合'''软件重用的重要方式除了继承之外还有另外一种方式,即:组合组合指的是,在一个类中以另外一个类的对象作为数据属性,称为类的组合 1. 什么是组合 一个对象的属性是来自于另外一个类的对象,称之 ...

  3. 单元测试-代码覆盖率 EclEmma

    1. EclEmma的介绍 EclEmma是一个开源的软件测试工具,可以在编码过程中查看代码调用情况.也可以检测单覆盖率. 2. Eclipse下EclEmma安装 1. 选择Help->Ecl ...

  4. 5个php实例,细致说明传值与传引用的区别

    传值:是把实参的值赋值给行参 ,那么对行参的修改,不会影响实参的值 传引用 :真正的以地址的方式传递参数传递以后,行参和实参都是同一个对象,只是他们名字不同而已对行参的修改将影响实参的值 说明: 传值 ...

  5. hdu3183 rmq求区间最值的下标

    两个月前做的题,以后可以看看,是rmq关于求区间最值的下标 /* hdu3183 终点 给一个整数,可以删除m位,留下的数字形成一个新的整数 rmq 取n-m个数,使形成的数最小 */ #includ ...

  6. gulp初探

    很多人都在用grunt和gulp,我现在连github都不用..为了说自己是个前端,还是搞搞gulp吧 nodejs很多人都会安装,这个不是问题 npm模块现在好像是自带的..我忘了.. 先全局安装下 ...

  7. P3331 [ZJOI2011]礼物(GIFT)

    题解: 首先转化为平面问题 对于每一个z,f(x,y)的值为它能向上延伸的最大高度 ...莫名其妙想出来的是n^4 以每个点作为右下边界n^3枚举再o(n)枚举左下边界计算z的最大值 然而很显然这种做 ...

  8. 【Java】 剑指offer(40) 最小的k个数

    本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集   题目 输入n个整数,找出其中最小的k个数.例如输入4.5.1.6.2.7 ...

  9. HDU 2612 find a way 【双BFS】

    <题目链接> 题目大意:两个人分别从地图中的Y 和 M出发,要共同在 @ 处会面(@不止有一处),问这两个人所走距离和的最小值是多少. 解题分析: 就是对这两个点分别进行一次BFS,求出它 ...

  10. ImportError: cannot import name cbook

    Faster RCNN训练的时候,出现错误: from matplotlib import path, transforms File , in <module> from . impor ...