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

      最近做一个项目,前端由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){
		/*
		*  $event是事件,dataObj是$scope.data中一个数据对象,
		*   name是是数据对象的具体属性名 
		*/
		
	    var obj = $event.target;	//获取被双击的对象
						
		//转换成由span转换为输入框
	    var input = document.createElement("input");
		input.value = obj.innerHTML;
		obj.parentNode.replaceChild(input,obj);
		
		//失去焦点时由input输入框转换为span
		input.onblur = function(){
		   obj.innerHTML = input.value;
		   
		   //改变双向绑定的数据,如果双向绑定的数据是是Number类型,
		   //则把input输入的值转换为Number值,这个可以根据实际需要进行转换
		   dataObj[name] = angular.isNumber(dataObj[name])?parseInt(input.value):input.value;
		   
		   input.parentNode.replaceChild(obj,input);
		   
		   //在console里打印结果,查看双向绑定的数据是否改变
		   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>


仅作为笔记记录。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值