Angular Recursive Directive with ngModel

Angular Recursive Directive with ngModel

本文关键字:ngModel with Directive Recursive Angular      更新时间:2023-09-26

我最近学到了很多关于递归指令的知识,但还有一些东西我还没有理解。

这篇文章特别解决了我的大部分问题:Angular 指令中的递归(谢谢!!

我已经设法基于这种技术构建了一个递归规则编辑器指令,它可以完成我想要的大部分工作。 它成功编辑了一个复杂的 JSON 结构,该结构描述了用于处理消息的规则,允许您添加和删除层次结构级别以及编辑值。

该指令被设计为简洁地实例化,如下所示:

<rule-element rule="<scope variable>"></rule-element>

理想情况下,我希望这个指令表现为表单的一部分,带有验证信号,我读到的所有内容都告诉我我需要使用 ngModel 进行绑定。 但是,该示例以及我的代码不使用 ngModel,而是选择使用属性和本地隔离范围。

我已经读到将ngModel与隔离作用域一起使用是很棘手的(ng-model依赖性的隔离作用域陷阱),而且我使用ngModel到达这里的途径并不是很成功,所以我最终只是在属性上使用双向绑定。

添加此元素所需的钩子以报告其包含的表单的最佳方法是什么,以便我可以使用角度验证来呈现消息并启用/禁用提交按钮?

我敢肯定我可以以某种方式破解它,但我这样做的主要动机是学习正确的方法,所以,呃,我来了。

以下是我正在进行的工作指令的大量内容:http://plnkr.co/edit/02b9zTS1O81wgVapn3eg?p=preview

有什么建议吗?

我也有复杂的验证要求。就我而言,我从服务器获得一个 json,其中包含相关输入字段的错误消息。它只依赖于字段名称(也是数组和嵌套,如 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;
    }
};

这是一个半答案。

我希望让元素自我验证,但我无法找到一种方法来将表单附加到它,而不会使表单成为递归的一部分并产生我尚未准备好解决的新问题。

因此,我最终构建了一个验证指令,该指令可以附加到元素以访问模型:

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