最近做一个项目,前端由Angular搭建,需要实现一个功能,就是双击进入编辑,当失去焦点的时候把数据保存。(即改变双向绑定的数据)。
先写一些简陋的HTML代码:
- <table class="table1">
- <tr>
- <td></td>
- <td></td>
- <td></td>
- </tr>
- </table>
测试的数据如下:
- $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}];
把数据显示在视图上:
- <table class="table1">
- <tr ng-repeat="item in data">
- <td>{{item.id}}</td>
- <td ng-dblclick="replace($event,item,'name')"><span>{{item.name}}</span></td>
- <td ng-dblclick="replace($event,item,'age')"><span>{{item.age}}</span></td>
- </tr>
- </table>
为了看起来舒服一些,随便写点样式:
- table td{
- width:200px;
- border:1px solid #ccc;
- text-align:center;
- }
- table td span{ //这个样式很重要,让span充满整个td,防止点击时,获取到的对象是td而不是span
- display:block;
- width:100%;
- height:100%;
- }
- table{
- border-collapse:collapse;
- }
显示的结果如下:
JS代码
- angular.module('test',[]).controller('testController',function($scope){
-
- $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}];
-
- $scope.replace = function($event,dataObj,name){
-
-
-
-
-
- var obj = $event.target;
-
-
- var input = document.createElement("input");
- input.value = obj.innerHTML;
- obj.parentNode.replaceChild(input,obj);
-
-
- input.onblur = function(){
- obj.innerHTML = input.value;
-
-
-
- dataObj[name] = angular.isNumber(dataObj[name])?parseInt(input.value):input.value;
-
- input.parentNode.replaceChild(obj,input);
-
-
- console.table($scope.data);
- };
-
- };
- });
实验结果:
但是做了一些测试后,发现了几个小问题,
问题1:当单击出现文本框后(此时只是出现文本框,但是焦点没在文本框上),再去点击其他数据,又出现文本框,之前那个文本框并没有转换为span。看下图:
解决方法,当span被input代替的时候,聚焦到input,input.focus();
问题2:当点击td时,转换为input后,点击同一个td的非input区域。
问题3:不停点击已经出现的input,会报错。出现下图现象。
问题2、问题3解决,判断是否是span节点,然后再赋予点击事件。obj.nodeName=='SPAN'
一个简单的双击进入编辑算是完成了。或许还有其他的bug,以后发现了,再做修改。
完整的代码如下所示:
- <!DOCTYPE>
- <html ng-app="test">
- <head>
- <script src="http://lib.sinaapp.com/js/angular.js/angular-1.2.19/angular.min.js"></script>
- <script>
- angular.module('test',[]).controller('testController',function($scope){
-
- $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}];
-
- $scope.replace = function($event,dataObj,name){
-
- var obj = $event.target;
-
- //当被双击的是span元素时,才执行事件
- if(obj.nodeName=='SPAN'){
-
- //转换成输入框
- var input = document.createElement("input");
- input.value = obj.innerHTML;
- obj.parentNode.replaceChild(input,obj);
- //聚焦的替换后的input上
- input.focus();
-
- input.onblur = function(){
- obj.innerHTML = input.value;
- dataObj[name] = angular.isNumber(dataObj[name])?parseInt(input.value):input.value;
- input.parentNode.replaceChild(obj,input);
- console.table($scope.data);
- };
- }
- };
- });
- </script>
- <style>
- table td{
- width:200px;
- border:1px solid #ccc;
- text-align:center;
- }
- table td span{
- display:block;
- width:100%;
- height:100%;
- }
- table{
- border-collapse:collapse;
- }
- </style>
- </head>
- <body ng-controller="testController">
- <table class="table1">
- <tr ng-repeat="item in data">
- <td>{{item.id}}</td>
- <td ng-dblclick="replace($event,item,'name')"><span>{{item.name}}</span></td>
- <td ng-dblclick="replace($event,item,'age')"><span>{{item.age}}</span></td>
- </tr>
- </table>
- </body>
- </html>