使用ngModel

时间:2016-01-19 00:11:28

标签: javascript angularjs recursion angularjs-directive angularjs-scope

我最近对递归指令有了很多了解,但还有一些我还没有完成的事情。

这篇文章特别解决了我的大部分问题: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

有什么建议吗?

2 个答案:

答案 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