Javascript 如何正确控制角指令的$dirty和$pristine状态
我试图创建一个angular指令,它将组成一个KendoUI TreeView控件和一个文本输入,以便它搜索输入的文本并选择项目。我有这个功能,但我希望该指令在表单中表现良好,以便在更改复选框值时设置表单的dirty属性 不幸的是,刚才的行为是,当有人在输入中输入文本时,from被设置为dirty(非期望的行为),并且选中复选框没有效果 我希望在表单上调用$setDirty(),但它对我拥有的函数不可见,我希望有一种干净的方法使它可见,而不是将它添加到$scope,这也不会解决$dirty设置为true但输入搜索文本的问题 我创建了一个示例来演示这个问题 以下是指令的代码:Javascript 如何正确控制角指令的$dirty和$pristine状态,javascript,angularjs,angularjs-directive,kendo-ui,Javascript,Angularjs,Angularjs Directive,Kendo Ui,我试图创建一个angular指令,它将组成一个KendoUI TreeView控件和一个文本输入,以便它搜索输入的文本并选择项目。我有这个功能,但我希望该指令在表单中表现良好,以便在更改复选框值时设置表单的dirty属性 不幸的是,刚才的行为是,当有人在输入中输入文本时,from被设置为dirty(非期望的行为),并且选中复选框没有效果 我希望在表单上调用$setDirty(),但它对我拥有的函数不可见,我希望有一种干净的方法使它可见,而不是将它添加到$scope,这也不会解决$dirty设置为
var serviceRoot=”http://demos.telerik.com/kendo-ui/service";
angular.module(“KendoDemos”[“kendo.directives”])
.controller(“MyCtrl”,函数($scope,$http){
$scope.treeData=new kendo.data.hierarchycalDataSource({
数据:[{
文本:“猫”
}, {
文字:“狗”,
项目:[{
案文:“Fido”
}, {
文字:“漫游者”
}]
}, {
文字:“兔子”,
核对:正确
}]
});
});
(功能(){
"严格使用",;
var app=angular.module('KendoDemos');
变量模板=“{dataItem.text}”
app.directive('searchableTree',function(){
//用法:
//
var指令={
模板:模板,
要求:“?^form”,
替换:正确,
是的,
范围:{
“数据源”:“=ngModel”,
“controlId”:“@id”
},
限制:“AE”,
链接:函数($scope、element、attrs、formCtrl){
$scope.search=函数(id){
var-tree=$scope.searchTree;
var node=tree.findByText($scope.searchText);
expandTo($scope.searchTree.dataItem(节点));
树。选择(节点);
tree.dataItem(node).set(“选中”,true);
//var checkbox=$(node.find(“:checkbox”);
//复选框.prop(“选中”,true);
}
$scope.setSelected=函数(id){
警报(id);
}
$scope.onSelect=函数(id){
警报(id);
}
$scope.onCheck=函数(e){
var checkbox=$(e.node.find(“:checkbox”);
var checked=checkbox.prop(“checked”);
//updateValidity(e.node,选中);
}
}
};
返回指令;
});
应用指令('ngEnter',函数(){
返回函数(范围、元素、属性){
元素绑定(“按键按下”,函数(事件){
if(event.which==13){
作用域$apply(函数(){
范围$eval(属性n中心);
});
event.preventDefault();
}
});
};
});
应用指令('ngEsc',函数(){
返回函数(范围、元素、属性){
元素绑定(“按键按下”,函数(事件){
if(event.which==27){
作用域$apply(函数(){
范围:$eval(属性ngEsc);
});
event.preventDefault();
}
});
};
});
})();代码>
/*样式在这里*/
html{
字体大小:12px;
字体系列:Arial、Helvetica、无衬线字体;
}
#范例{
文本对齐:居中;
}
.演示部分{
显示:内联块;
垂直对齐:顶部;
宽度:320px;
高度:300px;
文本对齐:左对齐;
边缘:0.2米;
}
.可点击{
光标:指针;
}
指令是{{myForm.myTree.$dirty?'dirty':'pristine'}
表单是{{myForm.$dirty?'dirty':'pristine'}
这里有几件事,因此,在不讨论特定指令的具体内容的情况下,您应该了解以下内容:
link: {
pre: function(scope, element){
// this will trip the search, and apply a `nullFormCtrl` internally,
// which doesn't do anything.
element.data("$formController", null);
}
}
ng型号:
您应该要求:“ngModel”
而不是将其用作范围变量ng model
是一个指令,通过它您可以与其他表单和验证器正确集成ng模型
是DOM不可知的,应该用作模型和视图值之间的概念管道
如果正确地执行此操作,则无需要求:“表单”
您有一个自定义输入控件:
认识到您正在有效地构建自定义输入指令。它以某种方式设置模型,并以某种方式呈现UI
查看Angular docs中有关创建自定义输入指令的内容
在自定义指令的模板中使用ng模型:
现在,您看到的$dirty
的问题是,指令内部的ng model
(ng model=“searchText”
)与外部表单集成,完全不知道它是另一个自定义输入控件的一部分
ngModel
指令在DOM层次结构中搜索(请参阅)表单指令,并最终找到指令所在的表单
处理此问题的一种方法是不要在模板中使用ng model
,而是在('input')
(或其他)上执行element.on来检测更改,并适当地设置“必需的”ngModel
的视图值
另一个是太“欺骗”了ngModel
,使其相信表单控制器为空,因此它不会更新它
这很容易做到,但我不能评论这是否是未来的证明。在指令的预链接中执行以下操作:
link: {
pre: function(scope, element){
// this will trip the search, and apply a `nullFormCtrl` internally,
// which doesn't do anything.
element.data("$formController", null);
}
}
2016年2月8日附录:写这篇文章后,我意识到scope方法仅在调试模式下可用。我不建议将此用于生产代码
<