具有ngModel的Angular递归指令

4
我最近学到了很多关于递归指令的知识,但还有一些问题我还不明白。
特别是这篇文章解决了我的大部分问题:Angular指令中的递归(谢谢!!)
我已经根据这种技术构建了一个递归规则编辑器指令,可以完成我想要的大部分功能。它成功地编辑了描述处理消息规则的复杂JSON结构,允许您添加和删除层次结构并编辑值。
该指令旨在像这样简洁地实例化:
<rule-element rule="<scope variable>"></rule-element>

理想情况下,我希望这个指令可以作为表单的一部分来使用,并且能够进行验证。但是,我读到的所有内容都告诉我需要使用ngModel进行绑定。然而,示例和我的代码并没有使用ngModel,而是选择使用属性和本地隔离作用域。
我已经了解到使用隔离作用域的ngModel比较棘手(参见Isolated scope pitfall with ng-model dependency),并且使用ngModel的过程中遇到了一些问题,所以最终我只是在属性上使用双向绑定。
那么,如何为此元素添加必要的钩子,以便它向包含它的表单报告,从而可以使用Angular验证来呈现消息并启用/禁用提交按钮?
我相信我可以通过某种方式来完成这个hack,但我的主要动机是学习正确的方法,所以我在这里。
以下是我正在进行中的指令的plunkr:http://plnkr.co/edit/02b9zTS1O81wgVapn3eg?p=preview 有什么建议吗?

为了先解决简单的问题,script.js:113:9 中的 controller 有一个拼写错误。 - mzulch
谢谢。我已经想到可以使用ngModel而不是属性,而且我已经让它工作了。(我很快会发布一个更新的plunkr)。现在的挑战是让指令与表单通信。由于我不能将所有递归级别都作为命名表单元素,因此我正在尝试在顶层添加一个属性指令来验证模型。 - Jim B.
2个回答

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;
    }
};

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);

        }
    };
});

我不喜欢的是,它有自己的递归来验证整个树(请参见 validate() 函数的 plunkr)。似乎有一个更好的解决方案,即元素本身在递归时报告验证。

所以,这个方法可行,但不如我希望的那么优雅。

这里是更新后的 plunkr:http://plnkr.co/edit/7I0fBZnTEU8Ss0ZYphsB?p=preview


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接