【问题标题】:AngularJS form validation with isolated scope具有隔离范围的 AngularJS 表单验证
【发布时间】:2014-08-13 03:16:56
【问题描述】:

我想使用 AngularJS 提供的内置表单验证。但是,在表单中,我使用了自定义指令,每个指令都有一个隔离范围。因此,表单元素无法访问绑定值。

知道如何解决这个问题吗?

或者,是否可以在不使用表单的情况下使用 AngularJS 验证?

ng-minlength 和 ng-required 指令不会触发表单验证。

<div ng-app="myApp" ng-controller="myCtrl">
    <form name="myForm" novalidate>
        <do-something ng-model="variable"></do-something>
        <h4 data-ng-if="myForm.myElement.$error.required">Please enter something</h4>
        <h4 data-ng-if="myForm.myElement.$error.greaterThanOne">Please enter a value greater than 1</h4>
        <h4 data-ng-if="myForm.myElement.$error.minLength">Please enter something longer than 1 digit</h4>
    {{myForm.myElement.$error}}     
    </form>
</div>

var app = angular.module('myApp', []);
app.controller('myCtrl', function ($scope) {
});
app.directive('doSomething', function () {
    return {
        restrict: 'E',
        require: '?ngModel',
        scope: {
            model: '=ngModel'
        },
        template: 
            '<div>' +
            '  <input name="myElement" ng-model="model" ng-required ng-minlength="1" />' +
            '</div>'
    }
});

完整的 Plunk 可以在这里找到:这是一个演示问题的 plunkr:http://plnkr.co/edit/iWyvX2?p=preview

【问题讨论】:

  • 您是否将值作为属性传递给您的指令?您应该能够将该特定值的范围设置为我认为的双向。我在这里做假设;发布小提琴。
  • 我已经发布了一个 plunkr 来说明这个问题。我已将属性传递给指令。你能看出什么不对吗?

标签: javascript forms angularjs validation


【解决方案1】:

好的,丹尼尔,我很感兴趣,所以我进一步研究了它。您的代码和@user3766487 之间的主要区别在于您使用的是指令元素和注入模板。我相信这引起了一些歧义(您会看到指令本身和注入输入元素都具有相同的名称属性)。模型的链接似乎也不太正常。

我已更改您的代码以替换模板,这使事情变得更简单了。它似乎工作:

http://plnkr.co/edit/eTSbjNe4KXW9IbUKtKuG

【讨论】:

  • 感谢您的帮助@ChrisBell。我想我们正在慢慢实现。是否可以使用标准角度验证指令(例如 ng-maxlength)?还是你总是必须使用 $setValidity?
【解决方案2】:

据我了解,是的,您必须使用表单进行验证。

我验证的方式是设置如下指令

module.directive('ngDoSomething', function() {
    restrict: 'A'
    require: '?ngModel',
    scope: {
        model: '=ngModel'
    }
    link: function($scope, element, attrs, ngModel) {
    $scope.$watch('model', function(val) {
        ngModel.$setValidity('required', !!val);
        ngModel.$setValidity('greaterThanOne', val > 1);
    }
});

然后使用html

<form name="somethingForm">
  <input name="somethingElement" data-ng-do-something data-ng-model="variable" />
  <h4 data-ng-if="somethingForm.somethingElement.$error.required">Please enter something</h4>
  <h4 data-ng-if="somethingForm.somethingElement.$error.greaterThanOne">Please enter a value greater than 1</h4>
</form>

希望对你有帮助

【讨论】:

  • 我发布了一个 plunkr (plnkr.co/edit/iWyvX2?p=preview),它更清楚地说明了我遇到的问题。我让你的代码工作,但不能让我的工作。有什么想法吗?
  • @DanielMackay 我感觉在你的例子中 myForm.myElement 将无法解决(由于隔离范围)。为什么必须使用带有自定义模板而不是输入的指令?
  • 是的,原因是我使用的一些指令比单个输入更复杂。我使用的大多数输入指令都结合了标签和输入。有些甚至更复杂,例如我们拥有的自定义单选按钮。
【解决方案3】:

ng-validators 将通过这 2 个更改按预期工作:

(1) 将属性名称改为“minlength”(而不是“minLength”):

<h4 data-ng-if="myForm.myElement.$error.minlength">

(2) 将 ng-required 设置为“true”:

<input name="myElement" ... ng-required="true">

将 minlength 设置为“1”不会做任何事情,因为当输入为空时,表单验证不会检查 minlength。如果您将 minlength 设置为“5”并在输入中键入一个字符,您将看到消息“请输入超过 5 位的内容”

http://plnkr.co/edit/porkuq5JcKDU89s8g8ZT?p=preview

您的自定义验证器“greaterThanOne”在 do-something 指令中定义。您可以通过添加名称属性来显示其消息,例如 myElementContainer:

<do-something name="myElementContainer" ng-model="myElement"></do-something>
  <h4 data-ng-show="myForm.myElementContainer.$error.greaterThanOne">Please enter a value greater than 1</h4>

我建议将另一个指令中的逻辑定义为输入元素的属性。

此外,建议使用 $validators 而不是调用 $setValidity: https://docs.angularjs.org/api/ng/type/ngModel.NgModelController

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-23
    • 2019-10-21
    • 1970-01-01
    • 2015-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多