AngularJS-保存和创建/发布的验证

AngularJS-保存和创建/发布的验证,angularjs,forms,validation,Angularjs,Forms,Validation,我们正在开发一个网站,允许产品经理保存和创建产品 保存对输入的任何数据都有一些基本的验证。 创建/发布具有所有验证,包括所需的数据检查 是否有一种好方法可以对一个表单进行两种不同类型的验证? 以下是我尝试过的几种方法: 需要ng <input type="text" name="planName" ng-model="vm.product.planName" ng-required="vm.publishAttempt" /> 这使得在单击“发布”按钮时,不触发带有ng requi

我们正在开发一个网站,允许产品经理保存和创建产品

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

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

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

需要ng

<input type="text" name="planName" ng-model="vm.product.planName" ng-required="vm.publishAttempt" />
这使得在单击“发布”按钮时,不触发带有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方式,我只是缺少了这种方式


我是个新手,我有没有遗漏什么明显的东西

我在编辑控制器上将vm.publishtrunt添加到我的视图模型中,并将其设置为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
    }
在发布时,我将publish标记为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();
        });
    }
}
    // 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();
        });
    }
}