【问题标题】:AngularJS - Validation for Saving and Creating/PublishingAngularJS - 保存和创建/发布的验证
【发布时间】:2015-01-02 20:00:38
【问题描述】:

我们正在开发一个网站,让产品经理可以保存和创建产品。

保存对输入的任何数据进行一些基本验证。 创建/发布具有所有验证,包括所需的数据检查。

有没有一种好方法可以对一个表单进行两种不同类型的验证?

以下是我尝试过的几种方法:

ng-必需

<input type="text" name="planName" ng-model="vm.product.planName" ng-required="vm.publishAttempt" />

我们的保存将表单标记为原始。

    function saveSuccess()
    {
        vm.editForm.$setPristine();
        vm.publishAttempt = false;
        vm.isLoading = false;
    }

这使得带有 ng-required 的表单输入在单击发布按钮时不会触发验证,并且设置了一个真值来验证它们。我看到的唯一解决方案是循环表单元素并将它们标记为脏。不过,这似乎是错误的方法。

    function publish()
    {
        vm.isLoading = true;
        vm.publishAttempt = true;

        angular.forEach(vm.editForm, function (field)
        {
            if (field && field.$pristine != null)
            {
                console.log(field);
                field.$setDirty();
            }
        });

        setTimeout(function()
        {
            if (vm.editForm.$invalid)
            {
                vm.isLoading = false;
                logger.error('Required data is missing. Please check the form and try again.');
            }
            else
            {
                if ($window.confirm('Are you sure you want to publish this product? Doing so will make this product available to everyone and any changes going forward will be considered corrections to the product. '))
                {
                    productService.publishProduct($routeParams.productId)
                        .then(publishSuccess, publishFail);
                }
                else
                {
                    vm.isLoading = false;
                    vm.publishAttempt = false;
                }
            }
        }, 1000);
    }

使用 fluentvalidation 进行后端验证

我们还使用 FluentValidation 进行后端验证。我已经尝试返回这些结果,但随后必须遍历所有结果并在表单上找到值并将其标记为无效。

    function publishSuccess(result)
    {
        if (!result.IsValid)
        {
            angular.forEach(result.errors, function(error)
            {
                // Map error back to input and set invalid.  
            });        
        }
        else
        {
            openDetail($routeParams.productId);
        }
        vm.isLoading = false;
    }

默认使用 jQuery 作为解决方案非常诱人,但必须有一种我只是缺少的 AngularJS 方式。

我对 Angular 还很陌生,我是否遗漏了任何明显的东西?

【问题讨论】:

    标签: angularjs forms validation


    【解决方案1】:

    我在编辑控制器的视图模型中添加了 vm.publishAttempt 并将其设置为 false。

    function Edit(productService, logger, $routeParams, $location, $timeout, $modal, ...)
    {
        var vm = this;
        vm.publishAttempt = false;
        vm.save = save;
        vm.publish = publish;
        // ...
    

    在视图中,我将 ng-required 属性放在发布所需的所有输入上。

    ng-required="vm.publishAttempt"
    

    保存时,我将 publishAttempt 设置为 false,以便从视图中清除所有发布特定错误。保存成功后,表单将恢复为原始状态。

        function save()
        {
            vm.publishAttempt = false;
    
            $timeout(function()
            {
                if (vm.editForm.$invalid)
                {
                    vm.isLoading = false;
                    logger.error('Required data is missing. Please check the form and try again.');
                }
                else
                {
                    productService
                        .saveProduct(vm.product)
                        .$promise
                        .then(saveSuccess, saveFail);
                }
            }, 500);
        }
    
        function saveSuccess()
        {
            vm.editForm.$setPristine();
            vm.publishAttempt = false;
        }
    
        function saveFail(error)
        {
            // Display errors
        }
    

    在发布时,我将 publishAttempt 标记为 true,然后使所有表单输入变脏以显示错误。然后我们检查表单是否无效。如果是,我们通过向浏览器发送记录器消息让用户知道。

        function publish()
        {
            vm.publishAttempt = true;
    
            setAllInputsDirty(vm.editForm);
    
            $timeout(function()
            {
                if (vm.editForm.$invalid)
                {
                    logger.error('Required data is missing. Please check the form and try again.');
                }
                else
                {
                    if ($window.confirm('Are you sure ... ?'))
                    {
                        productService.publishProduct($routeParams.productId)
                            .then(publishSuccess, publishFail);
                    }
                    else
                    {
                        vm.publishAttempt = false;
                    }
                }
            }, 500);
        }
    
        function publishSuccess(result)
        {
            // If there are errors display them. 
            // This shouldn't happen because the front end validation should find these first.
            // These are the server side errors from FluentValidation
            if (!result.IsValid)
            {
                $modal.open({
                    templateUrl: '/app/edit/server-errors.html',
                    controller: 'ServerErrors',
                    controllerAs: 'vm',
                    size: 'lg',
                    resolve: {
                        errors: function ()
                        {
                            return result.errors;
                        }
                    }
                });
    
                return;
            }
    
            openDetail($routeParams.productId);
            logger.info('Product successfully published.');
            vm.isLoading = false;
        }
    
        function publishFail(error)
        {
            vm.isLoading = false;
            logger.error('Publish failed', error);
        }
    

    这是用于使所有输入变脏以使条件验证为发布工作的方法。这是下面评论中 URL 的完整副本。

        // http://blog.pixelastic.com/2014/09/10/setting-all-inputs-as-$dirty-in-angularjs-1.2/
        function setAllInputsDirty(form)
        {
            _.each(form, function (value, key)
            {
                // We skip non-form and non-inputs
                if (!value || value.$dirty === undefined)
                {
                    return;
                }
    
                // Recursively applying same method on all forms included in the form
                if (value.$addControl)
                {
                    return setAllInputsDirty(value);
                }
    
                return value.$setDirty();
            });
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-22
      • 1970-01-01
      • 2013-04-10
      • 1970-01-01
      相关资源
      最近更新 更多