我怎么可以重写无效表单值角的过滤,迫使角度来持久$ viewValue至$ modelValue? [英] How can I override Angular's filtering of invalid form values, forcing Angular to persist the $viewValue to $modelValue?

查看:630
本文介绍了我怎么可以重写无效表单值角的过滤,迫使角度来持久$ viewValue至$ modelValue?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要能够暂时持久化尚未完全验证的数据,然后执行验证时,我已经准备好,使之永久化。但是角度是preventing这一点。

I need to be able to temporarily persist data that isn't fully validated yet, then enforce validation when I'm ready to make it permanent. But Angular is preventing that.

我有一个表格。在窗体的早期版本,它被保存到服务器的用户可以通过 saveDraft()。然后,当用户准备就绪后,他们可以提交()的形式,将不同的标志坚持它,从此开始了实际的数据处理。

I have a form. The user can saveDraft() on early versions of the form, which are persisted to the server. Then, when the user is ready, they can submit() the form, which will persist it with different flags, thus beginning the actual processing of that data.

我遇到的问题是有角的内置验证。当用户输入一些数据与上验证输入,数据被缓存在 $ viewValue 属性。但是,如果验证失败,它从来没有复制到 $ modelValue 属性,这是实际 $范围属性的引用我结合的输入。因此在无效值将不会被保留。

The problem I'm running into is with Angular's built-in validations. When a user enters some data into an input with validations on it, that data is cached on the $viewValue property. But if validation fails, it's never copied to the $modelValue property, which is a reference to the actual $scope property I bound the input to. And hence the 'invalid' value will not be persisted.

但是,我们必须坚持它。我们将处理强迫用户以后改正自己的验证失败,当他们提交()。此外,我们也没有办法知道用户是否会 saveDraft()提交()在一个特定的视图/控制器的情况下,所以我们不能设置的意见和不同的验证事前。

But we need to persist it. We'll deal with forcing the user to correct their validation failures later, when they submit(). Also, we have no way to know whether the user is going to saveDraft() or submit() on a particular instance of the view/controller, so we can't setup the views and validation differently beforehand.

我的想法是,我们需要以某种方式遍历表单元素,并得到角以某种方式让数据通过。但我不能找到一种方法,这就是灵活性和可扩展性。

My thinking is that we need to somehow iterate the form elements and get Angular to somehow let the data go through. But I can't find a way that's flexible and scalable.

我试过设置 $ scope.formName.inputName。$ modelValue = $ scope.formName.inputName。$ viewValue ,但似乎只是打乱了神,作为两个值然后null'ed。

I've tried setting $scope.formName.inputName.$modelValue = $scope.formName.inputName.$viewValue, but that seems to just upset the gods, as both values are then null'ed.

我已经使用 $ scope.formName.inputName。$ setValidity试过('',真),但只更新UI状态。它从不接触 $ modelValue

I've tried using $scope.formName.inputName.$setValidity('', true), but that only updates the UI state. It never touches $modelValue.

我可以成功地使用 $ scope.model.boundPropertyName = $ scope.formName.inputName。$ viewValue 但感觉很必要,也不会允许有任何差异为 boundPropertyName 标识和 inputName 。换句话说,您可能需要各个功能为所有表单控件,或者你需要依靠命名约定。这两者都是超脆。

I can successfully use $scope.model.boundPropertyName = $scope.formName.inputName.$viewValue but that feels very imperative and won't allow any variance between the identifiers for boundPropertyName and inputName. In other words, you either need individual functions for all form controls, or you need to rely on naming conventions. Both of which are super-brittle.

所以...我怎么能得到 $ modelValue 优雅更新?和/或是否有其他更好的方式来获得同样的结果,因此有时我可以验证坚持,有时坚持不?

So... how can I get that $modelValue updated elegantly? And/Or, is there another, better way to obtain the same results, whereby sometimes I can persist with validation, and sometimes persist without?

我考虑其他的选择,但不愉快的:

Other options I'm considering, but not happy with:


  • 运行验证手动,只有当用户点击提交()。但是,这违背了即时的UX值,在UI内嵌验证。我们还不如干脆卸载所有验证到服务器,每次做一个来回。

  • 请ngModel和ngModelController和复印件猴子修补它们更新 $ modelValue 无论有效性。但是黑客时应该有一个更优雅路径的框架。

  • Run validation manually, only when the user hits submit(). But that defeats the UX value of instant, inline validation in the UI. We might as well just offload all the validation to the server and do a round-trip each time.
  • Make copies of ngModel and ngModelController, and monkey-patch them to update $modelValue regardless of validity. But that hacks the framework when there should be a more elegant path.

见codePEN这里

(边注:角似乎是过滤数据根据审定的两个方向的如果你的模型的'1234'formData.zip,这ISN设置的默认值。 'T足够的字符来验证,角甚至不显示它。它从来没有达到最初的 $ viewValue

(Side-note: Angular appears to be filtering the data according to the validator in both directions. If you set a default value on the model for formData.zip of '1234', which isn't enough characters to validate, Angular doesn't even show it. It never reaches the initial $viewValue.)

推荐答案

埃米尔·盖伦面包车有<一个href=\"http://blog.jdriven.com/2013/09/how-angularjs-directives-renders-model-value-and-parses-user-input/\">blog帖子涵盖正是这个问题。我用自己的输入指令,它完美的作品。

Emil van Galen has a blog post that covers exactly this issue. I've used his input directive, which works perfectly.

正如他所指出的,NgModelController的$解析器数组是:

As he point out, The $parsers array of NgModelController is:

的函数来执行,作为管道,每当控制从DOM中读取数值数组。每个函数被调用,反过来,使数值通过到下一个。用于消毒/转换价值和验证。为了验证,解析器应该使用$ setValidity()更新有效期限状态,并为无效值返回undefined。

因此​​,要允许模型被更新到的无效的值,但仍保留了验证结果,创建指令不返回未定义无效值。例如,埃米尔的指示恢复无效的,不确定的字符串值模型值,否则返回该视图值:

So, to allow the model to be updated to an invalid value, yet retain the validation results, create a directive that does not return undefined for invalid values. For example, Emil's directive reverts invalid, undefined string values to the model value, otherwise it returns the view value:

angular.module('jdFixInvalidValueFormatting', [])
.directive('input', function() {
    return {
        require: '?ngModel',
        restrict: 'E',
        link: function($scope, $element, $attrs, ngModelController) {
            var inputType = angular.lowercase($attrs.type);

            if (!ngModelController || inputType === 'radio' ||
                    inputType === 'checkbox') {
                return;
            }

            ngModelController.$formatters.unshift(function(value) {
                if (ngModelController.$invalid && angular.isUndefined(value)
                        && typeof ngModelController.$modelValue === 'string') {
                    return ngModelController.$modelValue;
                } else {
                    return value;
                }
           });
       }
    };
});

您可以看到在他的Plunker工作(也注意,的改进处理自己的见解,而不是未定义):<一href=\"http://plnkr.co/edit/gist:6674554?p=$p$pview\">http://plnkr.co/edit/gist:6674554?p=$p$pview

You can see it working in his Plunker (also note his take on an improved handling of null rather than undefined): http://plnkr.co/edit/gist:6674554?p=preview

这篇关于我怎么可以重写无效表单值角的过滤,迫使角度来持久$ viewValue至$ modelValue?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆