基于优化的问题,input框内容变化,掉后台接口进行查询。
基于angular框架,使用ng-change指令,导致输入一个文本就会查询一次,频繁的掉接口,对服务器造成不必要的压力。
优化方案:
-
ng-change指令,但是添加延时,延时执行掉接口,这里延时多少才合适是个问题。
-
换成原生change事件,用户输入结束后,input失焦,才掉接口。这里碰到问题就是
onchange不会触发controller中的事件
,原因写法不对
。
1. 原生的onchange事件
- 行内写法
<label>请输入用户名:<input type="text" id="userName" onchange="upperCase(this.id)" /></label>
<script type="text/javascript">
function upperCase(id){
var name = document.getElementById(id).value;
document.getElementById(id).value = name.toUpperCase();
}
</script>
- 不写在行内
<label for="userName">请输入用户名:</label><input type="text" name="userName" id="userName">
<script>
var oInput = document.getElementById("userName");
oInput.onchange = function(){
this.value = this.value.toUpperCase();
}
</script>
2. angular 中的ng-change指令
- ng-change 要 配合 ng-model 使用
<input name="sqJob" type="text"
class="form-control ng-pristine ng-invalid ng-invalid-required ng-valid-maxlength ng-touched"
style="width: 400px;"
ng-model="indexE.businessObjVal"
ng-change = "indexE.showIndexSelectData()"
ng-maxlength="100" required
placeholder="请输入完整的{{indexE.businessObjName}}">
vm.showIndexSelectData = function(){
// do something
}
3. angular 中使用行内onchange事件,报错change对应的function未定义
解决:
- html 中 input 的 onchange 写法:
onchange="angular.element(this).scope().控制器中定义的functionName"
- 对应controller中定义的changeFunction,必须挂在$scope下:
$scope.控制器中定义的functionName = function(){};
<tr ng-class="{'has-error': myForm.businessObjVal.$error.maxlength}"
ng-show = "indexE.businessObj != '请选择业务对象类型'">
<td class="control-label label-left">
<span style="color:red;">*</span>
<span>{{indexE.businessObjName}}:</span>
</td>
<td>
<span style="display:inline-block">
<input name="sqJob" type="text" class="form-control ng-pristine ng-invalid ng-invalid-required ng-valid-maxlength ng-touched"
style="width: 400px;"
ng-model="indexE.businessObjVal"
onchange = "angular.element(this).scope().showIndexSelectData(this.name)"
ng-maxlength="100" required
placeholder="请输入完整的{{indexE.businessObjName}}">
</span>
<span style="color:red;display:inline-block" ng-show="myForm.businessObjVal.$error.maxlength">
<span>{{indexE.businessObjName}}描述应少于100字</span>
</span>
</td>
</tr>
//function showIndexSelectData(e){
$scope.showIndexSelectData = function(e){
console.log(e);
if(vm.bsResourceUseType != "请选择资源用途类型"){
vm.bsResourceUseType = "请选择资源用途类型";
var dropdownlist = $("#selectResourceUseTypedropdownlist").data("kendoDropDownList");
dropdownlist.text("请选择资源用途类型");
}
if(vm.selectIndexVal != "请选择关键技术指标" && vm.selectIndexVal != ""){
vm.selectIndexVal = "";
var dropdownlist2 = $("#selectTSIndexdropdownlist").data("kendoDropDownList");
dropdownlist2.text("请选择关键技术指标");
}
$("#grid").empty();
vm.getIndexData();
}
4. 两者的区别:
原生onchange 事件,需要在 文本框内容发生改变
且 input框失焦
之后才会触发。
angular中的 ng-change,只要 文本框内容发生改变
就会触发,无论input框是否失焦。
两者各有各自的优缺点,看各自的具体需要场景使用即可,关键的是看对input是否失焦这个点的需要。
5. 如果元素是使用ng-if控制显隐,不能使用document.getElementById
如果之前元素节点就不存在,使用原生的document.getElementById("id").onchange = function(){}
就会报错,因为没有这个节点,没法添加事件。
补救方法(节点比较多的情况下,不推荐):
if(document.getElementById("id")){
document.getElementById("id").onchange = function(){
// do something
}
}
或者jQuery:
jQuery无论是否节点存在,浏览器都并不会报错。但是使用$()
包裹之后返回的都是Object,要想判断是否存在,使用其类数组的性质if($(id).length > 0){}
网友评论