我最近对递归指令有了很多了解,但还有一些我还没有完成的事情。
这篇文章特别解决了我的大部分问题:Recursion in Angular directives(谢谢!)
我已经设法构建了一个基于这种技术的递归规则编辑器指令,该指令完成了我想要的大部分工作。它成功编辑了一个复杂的JSON结构,该结构描述了处理消息的规则,允许您添加和删除层次结构级别并编辑值。
该指令旨在简洁地实例化如下:
<rule-element rule="<scope variable>"></rule-element>
理想情况下,我希望此指令表现为表单的一部分,并提供验证信号,我读到的所有内容都告诉我需要使用ngModel进行绑定。但是,该示例以及我的代码不使用ngModel,而是选择使用属性和本地隔离范围。
我已经读过使用带有隔离范围的ngModel很棘手(Isolated scope pitfall with ng-model dependency),而且使用ngModel来到这里的重要路径并不是很成功,所以我最终只需对属性使用双向绑定。
添加此元素所需的挂钩以报告其所包含的表单的最佳方法是什么,以便我可以使用角度验证来显示消息并启用/禁用提交按钮?
我确定我可以以某种方式破解这个,但我这样做的主要动机是学习正确的方法,所以,呃,我在这里。
这是我正在进行的工作指令的一部分:http://plnkr.co/edit/02b9zTS1O81wgVapn3eg?p=preview
有什么建议吗?
答案 0 :(得分:1)
我也有复杂的验证要求。在我的例子中,我从服务器获得一个包含相关输入字段的错误消息的json。它只依赖于字段名称(也是数组和使用ng-repeat的嵌套,如attr [34] .part。这就是为什么我用有效标识符替换括号和点数。)
在这种情况下,我有一个范围对象包含所有属性的错误消息(我有另一个函数手动重置有效性,因为它会在另一个提交后仍然存在)。
我不知道这对你有用,但它可能会给你一个想法。
$scope.setValidationErrors = function ( error ) {
$scope.myForm.$setValidity( "validation", false );
if ( error.data ) {
// Add error messages
for ( var err in error.data ) {
var sanitizedErr = err.replace( /[.\[\]]/g, '-' );
if ( error.data.hasOwnProperty( err ) && $scope.showProviderForm[sanitizedErr] ) {
$scope.myForm[sanitizedErr].$setValidity( "validation", false );
$scope.myForm[sanitizedErr].$setPristine();
}
}
$scope.errors = error.data;
}
};
答案 1 :(得分:0)
这是一个半答案。
我希望让元素自我验证,但是我无法想出一种方法可以将表单附加到它上,而不会使表单成为递归的一部分并创建我不准备解决的新问题
因此,我最终建立了一个验证指令,可以附加到元素上以访问模型:
app.directive('ruleValid', function () {
return {
restrict: "A",
require: "ngModel",
link: function (scope, element, attrs, ngModel) {
scope.$watch(attrs.ngModel, function(thing) {
ngModel.$setValidity(attrs.ngModel, validate(thing));
}, true);
}
};
});
我不喜欢的是它有自己的递归来验证整个树(参见plunkr的validate()函数)似乎有一个更好的解决方案,元素本身在递归时报告验证。
所以,这有效,但并不像我希望的那样优雅。
这是更新的plunkr:http://plnkr.co/edit/7I0fBZnTEU8Ss0ZYphsB?p=preview