如何在自定义angular指令中添加/设置验证(require, prestine等)

How to add/set validations (require, prestine etc) on custom angular directives

本文关键字:require 验证 prestine 设置 自定义 angular 指令 添加      更新时间:2023-09-26

我已经创建了一个angular指令,如下所示:

angular.module('SharedModule')
    .directive('multiSelect', ['$ionicModal', multiSelect]);

function multiSelect($ionicModal) {
    return {
        restrict: 'E',
        template: [
            '<div ng-click="showItems($event)" class="item-icon-right item">',
            '{{text}}',
            '<i class="icon ion-ios-arrow-right"></i>',
            '</div>'
        ].join(""),
        scope: {
            'items': '=',
            'value': '=ngModel'
        },
        link: function (scope, element, attrs, $filter) {
            //validations
            //if (typeof attrs.required != "undefined"){
            //    // a value is required, hence invalidate this control.
            //
            //}
            //Some specific logic here. 
            scope.validate = function () {
                // validation that kicks in when user chooses to close the modal. 
            };
            scope.$on('$destroy', function () {
                scope.modal.remove();
            });
        }
    }
}

这基本上是给用户一个选项,从ionic应用中使用的模态对话框中选择多个联系人类型。

我使用这个指令在我的html(在一个表单中)如下:

<multi-select
    name="contactTypes"
    items="contact_types"
    text="Contact types"
    header-text="Choose contact types"
    allow-empty="false"
    ng-model="contact.contact_types"
    ></multi-select>

问题:如果用户没有选择任何东西,我不知道如何设置ng-pristine,ng-required,ng- unchanged类。管理自定义验证的代码放在哪里?我需要做些什么,这样我就可以使用这个指令作为任何其他输入控制与ng-model?

您将不得不与ng-model进行交互,如这里所述(特别是在"自定义控件示例"下)。总结:

  1. 首先要求ngModel:

    function multiSelect($ionicModal) {
        return {
            ...
            require: 'ngModel',
            ...
        };
    }
    
  2. link函数中得到ngModel并重新定义$isEmpty。默认值为undefined''nullNaN。您可能希望将空数组添加到此检查中,例如:

    link: function(scope, element, attrs, ngModel) {
        ...
        var originalIsEmpty = ngModel.$isEmpty;
        ngModel.$isEmpty = function(value) {
            return originalIsEmpty.call(ngModel, value) || value.length === 0;
        };
        ...
    }
    
  3. 完成后,您只需要将ng-required添加到您的指令:

    <multi-select ... ng-required="true"></multi-select>
    

    Angular将调用你自己的$isEmpty实现,并将ng-invalid-required类添加到<multi-select>元素中。

$pristine$untouched 可以开箱即用。如果没有,则必须添加调用ngModel的适当方法的代码:

  1. 每当用户打开对话框-控件被触摸时,执行ngModel.$setTouched()
  2. 每当用户在对话框中按下"OK"时,就会进行实际更改-控制值已经更改,它不再是原始的,执行ngModel.$setDirty()

顺便说一下,在link函数中访问ngModel使得scope: { 'value': '=ngModel' }是多余的。