实现双击进入编辑,失去焦点后保存数据(Angular)

最近做一个项目,前端由Angular搭建,需要实现一个功能,就是双击进入编辑,当失去焦点的时候把数据保存。(即改变双向绑定的数据)。

        先写一些简陋的HTML代码:
[html]  view plain  copy
  1. <table class="table1">  
  2. <tr>  
  3.     <td></td>  
  4.            <td></td>  
  5.            <td></td>  
  6. </tr>  
  7. </table>  

      测试的数据如下:

[javascript]  view plain  copy
  1. $scope.data = [{id:1,name:'huang',age:22},{id:2,name:'zhao',age:22},  
  2.                      {id:3,name:'zhou',age:20},{id:4,name:'sun',age:22}];  
       把数据显示在视图上:

[html]  view plain  copy
  1.    <table class="table1">  
  2.    <tr ng-repeat="item in data">  
  3.       <td>{{item.id}}</td>  
  4.       <td ng-dblclick="replace($event,item,'name')"><span>{{item.name}}</span></td>  
  5.       <td ng-dblclick="replace($event,item,'age')"><span>{{item.age}}</span></td>  
  6.    </tr>  
  7. </table>  
       为了看起来舒服一些,随便写点样式:
[css]  view plain  copy
  1. table td{  
  2.        width:200px;  
  3. border:1px solid #ccc;  
  4. text-align:center;  
  5. }  
  6. table td span{           //这个样式很重要,让span充满整个td,防止点击时,获取到的对象是td而不是span  
  7.        display:block;  
  8. width:100%;  
  9. height:100%;  
  10. }  
  11. table{  
  12.        border-collapse:collapse;  
  13. }  
      显示的结果如下:
  

JS代码

[javascript]  view plain  copy
  1. angular.module('test',[]).controller('testController',function($scope){  
  2.      
  3.  $scope.data = [{id:1,name:'huang',age:22},{id:2,name:'zhao',age:22},{id:3,name:'zhou',age:20},{id:4,name:'sun',age:22}];  
  4.    
  5.  $scope.replace = function($event,dataObj,name){  
  6.     /* 
  7.     *  $event是事件,dataObj是$scope.data中一个数据对象, 
  8.     *   name是是数据对象的具体属性名  
  9.     */  
  10.       
  11.     var obj = $event.target;    //获取被双击的对象  
  12.                       
  13.     //转换成由span转换为输入框  
  14.     var input = document.createElement("input");  
  15.     input.value = obj.innerHTML;  
  16.     obj.parentNode.replaceChild(input,obj);  
  17.       
  18.     //失去焦点时由input输入框转换为span  
  19.     input.onblur = function(){  
  20.        obj.innerHTML = input.value;  
  21.          
  22.        //改变双向绑定的数据,如果双向绑定的数据是是Number类型,  
  23.        //则把input输入的值转换为Number值,这个可以根据实际需要进行转换  
  24.        dataObj[name] = angular.isNumber(dataObj[name])?parseInt(input.value):input.value;  
  25.          
  26.        input.parentNode.replaceChild(obj,input);  
  27.          
  28.        //在console里打印结果,查看双向绑定的数据是否改变  
  29.        console.table($scope.data);  
  30.     };  
  31.       
  32.  };  
  33.   });  

实验结果:

但是做了一些测试后,发现了几个小问题,

问题1:当单击出现文本框后(此时只是出现文本框,但是焦点没在文本框上),再去点击其他数据,又出现文本框,之前那个文本框并没有转换为span。看下图:




解决方法,当span被input代替的时候,聚焦到input,input.focus();


问题2:当点击td时,转换为input后,点击同一个td的非input区域。



问题3:不停点击已经出现的input,会报错。出现下图现象。




问题2、问题3解决,判断是否是span节点,然后再赋予点击事件。obj.nodeName=='SPAN'
  

一个简单的双击进入编辑算是完成了。或许还有其他的bug,以后发现了,再做修改。


完整的代码如下所示:

[html]  view plain  copy
  1. <!DOCTYPE>  
  2. <html ng-app="test">  
  3. <head>  
  4. <script src="http://lib.sinaapp.com/js/angular.js/angular-1.2.19/angular.min.js"></script>  
  5. <script>  
  6.    angular.module('test',[]).controller('testController',function($scope){  
  7.       
  8.      $scope.data = [{id:1,name:'huang',age:22},{id:2,name:'zhao',age:22},{id:3,name:'zhou',age:20},{id:4,name:'sun',age:22}];  
  9.        
  10.      $scope.replace = function($event,dataObj,name){  
  11.           
  12.      var obj = $event.target;             
  13.       
  14.         //当被双击的是span元素时,才执行事件         
  15.         if(obj.nodeName=='SPAN'){  
  16.                   
  17.             //转换成输入框  
  18.             var input = document.createElement("input");  
  19.             input.value = obj.innerHTML;  
  20.             obj.parentNode.replaceChild(input,obj);  
  21.             //聚焦的替换后的input上  
  22.             input.focus();  
  23.               
  24.             input.onblur = function(){  
  25.                obj.innerHTML = input.value;  
  26.                dataObj[name] = angular.isNumber(dataObj[name])?parseInt(input.value):input.value;  
  27.                input.parentNode.replaceChild(obj,input);  
  28.                console.table($scope.data);  
  29.             };        
  30.         }                                     
  31.      };  
  32.    });  
  33. </script>  
  34. <style>  
  35.    table td{  
  36.            width:200px;  
  37.       border:1px solid #ccc;  
  38.       text-align:center;  
  39.    }  
  40.    table td span{  
  41.           display:block;  
  42.       width:100%;  
  43.       height:100%;  
  44.    }  
  45.    table{  
  46.       border-collapse:collapse;  
  47.    }  
  48. </style>  
  49. </head>  
  50. <body ng-controller="testController">  
  51.     <table class="table1">  
  52.        <tr ng-repeat="item in data">  
  53.           <td>{{item.id}}</td>  
  54.           <td ng-dblclick="replace($event,item,'name')"><span>{{item.name}}</span></td>  
  55.           <td ng-dblclick="replace($event,item,'age')"><span>{{item.age}}</span></td>  
  56.        </tr>  
  57.     </table>  
  58. </body>  
  59. </html>  

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值