angular.module('ExampleApp', [])
.controller('firstCtrl', function($scope) {
$scope.sampleItem = {
sampleName: "1234"
};
$scope.change = function(val) {
console.log(val);
}
})
.directive("useModel", ["SelectManager",
function(SelectManager) {
return {
restrict: "A",
scope: {
useModel: "=",
useModelReplacment: "@",
useModelCharacterShow: "=",
useChange: "&"
},
link: function(scope, elem) {
if (!angular.isDefined(scope.useModelCharacterShow))
scope.useModelCharacterShow = 0;
if (scope.useModelReplacment == undefined)
scope.useModelReplacment = "*";
if (scope.useModel == undefined)
scope.useModel = "";
else
elem.val(getMaskValue(scope.useModel));
scope.$watch('useModel', function(val) {
elem.val(getMaskValue(val));
if (scope.useChange)
scope.useChange();
})
function getMaskValue(val) {
var maskVal = "";
for (var i = 0; i < val.length; i++) {
if (scope.useModelCharacterShow > 0) {
if (i >= scope.useModelCharacterShow)
maskVal += scope.useModelReplacment;
else
maskVal += val[i];
}
if (scope.useModelCharacterShow < 0) {
if (i < val.length + scope.useModelCharacterShow)
maskVal += scope.useModelReplacment;
else
maskVal += val[i];
}
if (scope.useModelCharacterShow == 0) {
maskVal += scope.useModelReplacment;
}
}
return maskVal;
}
function onKeyPressed(event) {
if (event.ctrlKey && (event.charCode == 99 || event.charCode == 118 || event.charCode == 97 || event.charCode == 120))
return true;
var key_code = event.charCode;
var input = event.srcElement || event.target;
var ch = String.fromCharCode(key_code);
var start = SelectManager._getSelectionStart(input);
var end = SelectManager._getSelectionEnd(input);
// console.log('start end', start,end);
scope.useModel = scope.useModel.substr(0, start) + ch + scope.useModel.substr(end);
// console.log('inner value onKeyPressed', scope.useModel);
scope.$apply();
//console.log('show value onKeyPressed', maskVal);
//input.value = getMaskValue(scope.useModel);
event.returnValue = false;
SelectManager._setSelection(input, start + 1, start + 1);
return false;
}
function onKeyUp(event) {
if (event.ctrlKey && (event.charCode == 99 || event.charCode == 118 || event.charCode == 97 || event.charCode == 120))
return true;
var key_code = event.keyCode;
if (!(key_code == 13 || key_code == 27 || key_code == 8 || key_code == 46))
return true;
var input = event.srcElement || event.target;
var start = SelectManager._getSelectionStart(input);
var end = SelectManager._getSelectionEnd(input);
// console.log('start end', start,end);
if (key_code == 8 && start == end) {
start--;
}
if (key_code == 46 && start == end) {
//start++;
end++;
}
//console.log('inner value keyup', scope.useModel);
scope.useModel = scope.useModel.substr(0, start) + scope.useModel.substr(end);
//console.log('inner value keyup', scope.useModel);
scope.$apply();
//input.value = getMaskValue(scope.useModel);;
event.returnValue = false;
SelectManager._setSelection(input, start, start);
return event.returnValue;
}
function onKeyDown() {
var key_code = event.keyCode;
if (!(key_code == 13 || key_code == 27 || key_code == 8 || key_code == 46))
return true;
event.returnValue = false;
return event.returnValue;
}
function onPaste(event) {
var input = event.srcElement || event.target;
var ch = "";
if (event.type == "drop") {
event.returnValue = false;
return false
}
if (event.type == "paste")
ch = event.clipboardData.getData("text");
var start = SelectManager._getSelectionStart(input);
var end = SelectManager._getSelectionEnd(input);
// console.log('start end', start,end);
scope.useModel = scope.useModel.substr(0, start) + ch + scope.useModel.substr(end);
// console.log('inner value onKeyPressed', scope.useModel);
scope.$apply();
//input.value = getMaskValue(scope.useModel);
event.returnValue = false;
SelectManager._setSelection(input, start + ch.length, start + ch.length);
return false;
}
elem.on('keypress', onKeyPressed);
elem.on('keyup', onKeyUp);
elem.on('keydown', onKeyDown);
elem.on('paste drop', onPaste);
},
};
}
])
.service('SelectManager', function() {
return {
_getSelectionStart: function(obj) {
var p = 0;
if (obj.selectionStart) {
if (typeof(obj.selectionStart) == "number") p = obj.selectionStart;
} else if (document.selection) {
var r = document.selection.createRange().duplicate();
r.moveEnd("character", obj.value.length);
p = obj.value.lastIndexOf(r.text);
if (r.text == "") p = obj.value.length;
}
return p;
},
_getSelectionEnd: function(obj) {
var p = 0;
if (obj.selectionEnd) {
if (typeof(obj.selectionEnd) == "number") {
p = obj.selectionEnd;
}
} else if (document.selection) {
var r = document.selection.createRange().duplicate();
r.moveStart("character", -obj.value.length);
p = r.text.length;
}
return p;
},
GetXY: function(obj) {
var x = 0;
var y = 0;
while (obj.offsetParent) {
x += obj.offsetLeft;
y += obj.offsetTop;
obj = obj.offsetParent;
}
return {
X: x,
Y: y
};
},
_setSelection: function(obj, a, b) {
if (obj.setSelectionRange) {
obj.focus();
obj.setSelectionRange(a, b);
} else if (obj.createTextRange) {
var r = obj.createTextRange();
r.collapse();
r.moveStart("character", a);
r.moveEnd("character", (b - a));
r.select();
}
},
_Collapse: function(obj) {
var r = obj.createTextRange();
r.collapse();
}
};
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.js"></script>
<div ng-app="ExampleApp">
<div ng-controller="firstCtrl">
use-model(first three) <input use-model="sampleItem.sampleName" use-change="change(sampleItem.sampleName)" use-Model-Character-Show="3">
<br> use-model(last three) <input use-model="sampleItem.sampleName" use-change="change(sampleItem.sampleName)" use-Model-Character-Show="-3">
<br> ng-model <input ng-model="sampleItem.sampleName">
<pre> {{sampleItem.sampleName}}</pre>
<button ng-click="sampleItem.sampleName='AAAAA'">
set AAAAA
</button>
</div>
</div>
你可以嘗試使用NG-模型的getter/setter https://docs.angularjs.org/api/ng/directive/ngModel#binding-to-a-getter- setter – jcubic
@jcubic不幸的是,我找不到任何方式使用這個在我的方式,但我會繼續挖 –