cari

Rumah  >  Soal Jawab  >  teks badan

angular.js - 多重自定义指令应该怎么写?

是这样的,要创建一个登录用的东西,但卡在自定义指令上。
登录要求有一个账号输入框,一个密码输入框。

  1. 因为要兼容IE8,所以PLACEHOLDER属性不能直接用。需要使用自定义指令来完成。

  2. 账号可以是手机,也可以是邮箱,也可以是普通账号。

  3. 邮箱需要自动生成后缀,所以也需要自定义指令。可以设定是否需要在输入了@之后再显示邮箱提示。

  4. 账号需要可以自己验证,这又要引入自定义指令来写验证(从angular官网上看到的方法,自定义验证器)。

现在要使用多重自定义指令,来完成这个东西(如果大家有更好的办法,也可以不用这个,请告诉我,谢谢)。

我的想法是,先定义一个自定义指令,可以让它的PLACEHOLDER在需要的时候显示出来。然后在此基础上定义一个EMAIL指令,当输入账号的时候,自动给它加上各种域名的后缀,以供选择。最后再在这个基础上,定义一个PASSPORT指令,可以判断当前输入的内容是不是可用的账号(手机/邮箱/普通用户名)。

但是问题来了,如果要在同一个作用域中使用多个这种自定义指令的话,指令就必须是分离作用域,但是这三层的自定义指令,没办法都定分离作用域,会报错。如果要使各个此种指令分离的话,想到使用ng-repeat,但是ng-repeat生成的class又没办法在生成之后,自动编译成正常的指令……

我知道我说的有点儿乱,如果大家有别的好办法,请交流一下,谢谢。最后上代码……

主文件

<body ng-app="Main">

    <form novalidate name="LoginForm">
        <p ng-form class="dir-text-placeholder dir-text-email dir-text-passport" 
            ng-init="needAt=true; 
            name='user_passport'; 
            id='user_passport'; 
            placeholder='用户名/邮箱/手机';">
        </p>
    </form>

</body>
angular.module('Main', [])
    .directive('dirTextPlaceholder', [function () {
        return {
            restrict: 'C',
            priority:111,
            controller:function(){
                console.info('in textPlaceholder')
            },
            link: function (scope, iElement, iAttrs) {
                var input=iElement.find('input').eq(0);
                scope.$watch("value",function(newValue,oldValue){
                    if(!!newValue && !oldValue) 
                        input.addClass("chi-full").removeClass("chi-empty");
                    else if(!newValue && !!oldValue) 
                        input.addClass("chi-empty").removeClass("chi-full");
                });
            },
            templateUrl:"text-placeholder.html"
        };
    }])
    .directive('dirTextEmail', ['$compile','$timeout',function ($compile,$timeout) {
        var hosts='126.com|163.com|qq.com|sina.com|yeah.net'.split('|');
        return {
            restrict: 'C',
            priority:11,
            require: '?dirTextPlaceholder',
            controller:function(){
                console.info('in textEmail')
            },
            link: function (scope, iElement, iAttrs) {
                iElement.append("<ul></ul>")
                var input=iElement.find('input').eq(0),
                    ul=iElement.find('ul').eq(0),
                    li=angular.element('<li ng-repeat="email in emails | filter:host" ng-click="setEmail(email)">{{email}}</li>');
                $compile(li)(scope);
                ul.append(li);
                scope.$watch("value",function(newValue){
                    if(newValue===undefined) return false;
                    var indexAt=newValue.indexOf('@');
                    if(scope.needAt && !~indexAt) return false;
                    scope.host=newValue.substring(indexAt);
                    var passport=newValue.substring(0,indexAt);
                    var emails=[];
                    for(var n=0;n<hosts.length;n++) emails.push(passport+'@'+hosts[n]);
                    scope.emails=emails;
                    emails=null;
                    $timeout(function(){
                        if(ul.children().length==1 && ul.children().eq(0).html()==newValue)
                            ul.hide();
                        else ul.show();
                    });
                });
                scope.setEmail=function(email){
                    scope.value=email;
                }
            }
        };
    }])
    .directive('dirTextPassport', ['$rootScope',function ($rootScope) {
        return {
            restrict: 'C',
            priority:1,
            require: '?dirTextEmail',
            controller: function(){
                console.info('in textPassport')
            },
            link: function (scope, iElement, iAttrs) {
                var ptr=/^\w[-\w.+]*@([A-Za-z0-9][-A-Za-z0-9]+\.)+[A-Za-z]{2,14}|(13\d|14[57]|15[^4,\D]|17[678]|18\d)\d{8}|170[059]\d{7}$/,
                    input=iElement.find('input').eq(0),
                    controller=angular.element(iElement).scope();
                console.log($rootScope)
                //写到这儿的时候,想起来,账号跟密码要放在同一个作用域下,
                //所以第一个指令不采用分离作用域是不行的,但是分离之后,
                //后续的跟它作用在同一DOM上的其它指令又不能再用分离作用域,我就不会了……
            }
        };
    }])

模板文件text-placeholder.html

<input type="{{type}}" name="{{name}}" id="{{id}}" ng-model="value" autocomplete="off">
<label for="{{id}}">{{placeholder}}</label>
曾经蜡笔没有小新曾经蜡笔没有小新2744 hari yang lalu684

membalas semua(2)saya akan balas

  • phpcn_u1582

    phpcn_u15822017-05-15 17:05:52

    Ini ialah penyelesaian untuk keserasian pemegang tempat IE8.
    Saya secara peribadi tidak mengesyorkan anda menulis arahan untuk melengkapkan keperluan anda, logiknya terlalu mengelirukan. Ia tidak bermakna bahawa kemuncak sudut ialah arahan, dan arahan mesti dieksport. Ia hanyalah antara muka log masuk, dan logik pengesahan boleh ditulis kepada pengawal Jika anda mendapat arahan untuk menulisnya, jumlah kod akan sekurang-kurangnya dua kali ganda, dan kebolehbacaan tidak akan baik.

    balas
    0
  • 过去多啦不再A梦

    过去多啦不再A梦2017-05-15 17:05:52

    Sekolah terbengkalai^^^

    balas
    0
  • Batalbalas