實現雙擊進入編輯,失去焦點後儲存資料(Angular)
阿新 • • 發佈:2019-01-29
最近做一個專案,前端由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>
僅作為筆記記錄。