自定义指令选择需要 [英] required on custom directive select

查看:43
本文介绍了自定义指令选择需要的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用无序列表和 ng-repeat 创建了自己的选择下拉列表.该指令的问题在于它不能作为普通的 select/input/textarea 工作,您可以在 html 表单中使用 required 时使用它.

那么我如何实现选项 required/ng-required(作为指令)并验证自定义指令?

我应该使用自己的验证实现吗?

dropdown.html

<div class="title"ng-class="{'placeholder': !hasSelected(), 'selected': isOpened}"ng-mousedown="openSelect()">{{getTitle()}}<div class="icon" ng-class="{'active': isOpened}"><i class="fa fa-caret-down"></i>

<!-- 打开选择下拉菜单时显示的选项--><div class="选项"><ul ng-show="isOpened"><!-- 只有在需要空选项时才显示第一个选项 --><li ng-click="select(null)"ng-show="hasEmptyOption() && isSelected()"类=空">{{空的}}<!-- 选择的选项--><li ng-repeat="$index 选项中的选项"ng-click="选择($index)"ng-class="{'active': isActive($index)}">{{选项}}

dropdown.js

app.module.directive('dropdown', ['$document',功能($文档){'使用严格';返回{限制:E",范围: {型号:=",空的: "@",信息: "@",选项:="},templateUrl: 'app/common/directive/dropdown/dropdown.partial.html',链接:函数(范围,元素,属性){scope.message = "我的消息";scope.isOpened = false;scope.isSelected = 函数 () {返回 scope.model &&scope.model !== null;};scope.hasEmptyOption = 函数 () {返回 scope.empty &&scope.empty !== null;};scope.hasSelected = 函数 () {返回(范围.selected);};scope.select = 函数(索引){如果(索引!== 空){scope.model = scope.options[index];} 别的 {scope.model = null;}范围.closeSelect();};scope.closeSelect = function () {scope.isOpened = false;$document.unbind('点击');elem.unbind('点击');};scope.openSelect = 函数 () {如果(范围.isOpened){范围.closeSelect();} 别的 {scope.isOpened = true;$document.bind('click', function () {范围.closeSelect();范围.$应用();});elem.bind('click', function (e) {e.stopPropagation();});}};scope.getTitle = 函数 () {if (scope.model && scope.model !== null) {返回范围.模型;} else if (scope.message) {返回范围.消息;} 别的 {返回选择";}};}};}]);

使用

<dropdown message="Select state" model="selectedState" options="states" empty="unselect"></dropdown>

预览

解决方案

我觉得这个问题有点太快了.对不起.但答案对其他人非常有用

使用

</dropdown>

validation_dropdown.js

稍微更改了指令,以便更好地理解,添加注释

/*** 基于* http://stackoverflow.com/questions/24692775/angularjs-setvalidity-causing-modelvalue-to-not-update*/app.module.directive('validDropDown', [功能 () {返回 {要求:'ngModel',链接:函数(范围、元素、属性、ngModel){//创建验证器ngModel.$validators.validDropDown = 函数 (modelValue, viewValue) {/* 当没有值存在时 */var isValid;if (!modelValue || modelValue.length === 0) {isValid = false;} 别的 {isValid = true;}/* 设置所需的验证器,因为这不是标准的 html 表单输入 */ngModel.$setValidity('required', isValid);/* 设置自定义验证器 */ngModel.$setValidity('validDropDown', isValid);/* 返回模型以便模型在视图中更新 */返回模型值;};//观察模型的变化scope.$watch(attr.ngModel, function () {/* 当模型之前被触摸 */如果(ngModel.$touched){/* 当模型不脏时,通过重新应用其内容将 ngModel 设置为脏 */如果 (!ngModel.$dirty) {ngModel.$setViewValue(ngModel.$modelValue);}}/* 当模型有值时 */如果(ngModel.$modelValue){/* 当之前没有接触过模型时 */如果(!ngModel.$touched){ngModel.$setTouched();}}返回 ngModel;});//创建时验证ngModel.$validate();}}}]);

I have created my own select dropdown using an unordered list and ng-repeat. The problem with this directive is that it does not work as a normal select/input/textarea where you can use required when using it in a html form.

So how do I implement the option required/ng-required (as directive) with validation on a custom directive?

Should I use an own implementation of the validation?

dropdown.html

<!-- displayed text on the select -->
<div class="title"
     ng-class="{'placeholder': !hasSelected(), 'selected': isOpened}"
     ng-mousedown="openSelect()">
    {{getTitle()}}

    <div class="icon" ng-class="{'active': isOpened}">
        <i class="fa fa-caret-down"></i>
    </div>
</div>

<!-- displayed options when opening the select dropdown -->
<div class="options">
    <ul ng-show="isOpened">

        <!-- First option is only shown when an empty option is required -->
        <li ng-click="select(null)"
            ng-show="hasEmptyOption() && isSelected()"
            class="empty">
            {{empty}}
        </li>

        <!-- Options of the select -->
        <li ng-repeat="option in options track by $index"
            ng-click="select($index)"
            ng-class="{'active': isActive($index)}">
            {{option}}
        </li>
    </ul>
</div>

dropdown.js

app.module.directive('dropdown', ['$document',
    function ($document) {
        'use strict';

        return{
            restrict: "E",
            scope: {
                model: "=",
                empty: "@",
                message: "@",
                options: "="
            },
            templateUrl: 'app/common/directive/dropdown/dropdown.partial.html',
            link: function (scope, elem, attrs) {
                scope.message = "My message";
                scope.isOpened = false;

                scope.isSelected = function () {
                    return scope.model && scope.model !== null;
                };

                scope.hasEmptyOption = function () {
                    return scope.empty && scope.empty !== null;
                };

                scope.hasSelected = function () {
                    return (scope.selected);
                };

                scope.select = function (index) {
                    if (index !== null) {
                        scope.model = scope.options[index];
                    } else {
                        scope.model = null;
                    }
                    scope.closeSelect();
                };

                scope.closeSelect = function () {
                    scope.isOpened = false;
                    $document.unbind('click');
                    elem.unbind('click');
                };

                scope.openSelect = function () {
                    if (scope.isOpened) {
                        scope.closeSelect();
                    } else {
                        scope.isOpened = true;
                        $document.bind('click', function () {
                            scope.closeSelect();
                            scope.$apply();
                        });
                        elem.bind('click', function (e) {
                            e.stopPropagation();
                        });
                    }
                };

                scope.getTitle = function () {
                    if (scope.model && scope.model !== null) {
                        return scope.model;
                    } else if (scope.message) {
                        return scope.message;
                    } else {
                        return "Select";
                    }
                };
            }
        };
    }
]);

usage

<dropdown message="Select state" model="selectedState" options="states" empty="unselect"></dropdown>

Preview

解决方案

I Think I was a bit to fast with the question. Sorry for that. But the answer is very usable for everybody else

usage

<dropdown message="Select state" model="selectedState" options="states" empty="unselect" valid-drop-down></dropdown>

validation_dropdown.js

[EDIT] changed directive a bit so it is better to understand, added comment

/**
 * Based on
 * http://stackoverflow.com/questions/24692775/angularjs-setvalidity-causing-modelvalue-to-not-update
 */
app.module.directive('validDropDown', [
    function () {
        return {
            require: 'ngModel',
            link: function (scope, elem, attr, ngModel) {

                // Create validators
                ngModel.$validators.validDropDown = function (modelValue, viewValue) {
                    /* When no value is present */
                    var isValid;
                    if (!modelValue || modelValue.length === 0) {
                        isValid = false;
                    } else {
                        isValid = true;
                    }

                    /* Set required validator as this is not a standard html form input */
                    ngModel.$setValidity('required', isValid);

                    /* Set custom validators */
                    ngModel.$setValidity('validDropDown', isValid);

                    /* Return the model so the model is updated in the view */
                    return modelValue;
                };

                // Watch for changes to the model
                scope.$watch(attr.ngModel, function () {

                    /* When the model is touched before */
                    if (ngModel.$touched) {
                        /* When the model is not dirty, Set ngModel to dirty by re-applying its content */
                        if (!ngModel.$dirty) {
                            ngModel.$setViewValue(ngModel.$modelValue);
                        }
                    }

                    /* When the model has a value */
                    if (ngModel.$modelValue) {
                        /* When the model is not touched before */
                        if (!ngModel.$touched) {
                            ngModel.$setTouched();
                        }
                    }

                    return ngModel;
                });

                // Validate on creation
                ngModel.$validate();
            }
        }
    }
]);

这篇关于自定义指令选择需要的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆