【问题标题】:Angular Recursive Directive with ngModel使用 ngModel 的 Angular 递归指令
【发布时间】:2016-01-19 00:11:28
【问题描述】:

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

这篇文章特别解决了我的大部分问题:Recursion in Angular directives(谢谢!!)

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

该指令旨在简洁地实例化如下:

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

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

我读到使用带有隔离作用域的 ngModel 很棘手 (Isolated scope pitfall with ng-model dependency),而且我使用 ngModel 到达这里的打地鼠路径不是很成功,所以我最终只使用了双向绑定在一个属性上。

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

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

这是我正在进行的工作指令的一个 plunkr:http://plnkr.co/edit/02b9zTS1O81wgVapn3eg?p=preview

有什么建议吗?

【问题讨论】:

  • 为了把简单的东西排除在外,controllerscript.js:113:9 中有一个错字
  • 谢谢。我发现我可以使用 ngModel 而不是属性,并且我可以正常工作。 (我会尽快发布更新的 plunkr)。现在的挑战是让指令与表单进行通信。由于我不能将所有级别的递归都作为命名的表单元素,因此我试图在顶层添加一个属性指令来验证模型。

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


【解决方案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;
    }
};

【讨论】:

    【解决方案2】:

    这是一个半答案。

    我希望元素能够自我验证,但我想不出一种方法来将表单附加到它而不使表单成为递归的一部分并产生我还没有准备好解决的新问题.

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

    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

    【讨论】:

      猜你喜欢
      • 2013-01-04
      • 2017-06-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-01
      • 1970-01-01
      • 2016-10-02
      • 2016-06-23
      相关资源
      最近更新 更多