0

У меня есть директива AngularJS, которую я использую, чтобы экспериментировать с проверкой поля замедленной формы, как на размытие, так и на холостом ходу (без ввода в течение некоторого времени). У меня есть два подхода: один - добавить класс в фактическое поле ввода, а другой - установить переменную состояния в области. Установка класса подходит для стилизации поля, но я больше интересуюсь стилем (ng-показом) справочных сообщений, которые находятся на несвязанном элементе. Кроме того, класс может быть добавлен с ng-классом, поэтому подход, который я хочу, кажется, должен быть проверкой свойства переменной состояния.Директива AngularJS, которая отображает состояние представления

Моих вопросы:

  1. Есть ли способ, что я могу легко разоблачить IsActive состояния из директивы таким образом, что абоненты не должен проходить во внешней собственности выступать в качестве посредника? Это действительно не внешнее состояние, оно ориентировано на все, и я просто хочу получить к нему доступ из HTML.
  2. Каковы $ error, $ invalid и т. Д., Прикрепленные к элементу? Могу ли я создать такую ​​же функциональность в коде пользователя? т.е. element.state.active?

<form name="f"> 
     <div class="form-group" ng-class="{'has-error': f.e.$invalid}"> 
      <label>Enter Email Address</label> 
      <input type="email" class="form-control" name="e" ng-model="user.email" required autofocus active="1500" is-active="state.active"/> 
      <p class="help-block" ng-show="!state.active && f.e.$error.required">email is required</p> 
      <p class="help-block" ng-show="!state.active && f.e.$error.email">enter a valid email address</p> 
      <p class="help-block" ng-show="state.active">typing...</p> 
      <p class="help-block" ng-show="!state.active && f.$valid">ok!</p> 

     </div> 
    </form> 

И ассоциированная директива ...

app.directive('active', ['$parse', function ($parse) { 
     var tid; 
     return { 
      restrict: 'A', 
      require: '?ngModel', 
      scope: 
      { 
       isActive: "=", 
       ngModel: "=" 
      }, 

      link: function (scope, elem, attrs, ctrl) { 
       elem.bind('blur', function() 
       { 
        scope.isActive = false; 
        elem.removeClass("ng-active"); 
       }); 
       var timeout = attrs.active || 2000; 
       ctrl.$parsers.unshift(function(value) 
       { 
        scope.isActive = true; 
        console.log("adding class"); 
        elem.addClass("ng-active"); 
        if (tid) clearTimeout(tid); 

        tid = setTimeout(function() 
        { 
         console.log("timeout elapsed, removing class"); 
         scope.$apply(function(){ 
         scope.isActive = false; 
         }); 
         elem.removeClass("ng-active") 


        }, timeout); 
        return value; 
       }) 


      } 
     }; 
    }]); 

//myApp.directive('myDirective', function() {}); 
//myApp.factory('myService', function() {}); 

function TestCtrl($scope) 
{ 
    $scope.testName = "Validation Test"; 
    $scope.user = { 
     email: '[email protected]' 
    }; 
    $scope.state = { 
     active: false 
    }; 

} 

Вот a fiddle of this code running

В основном, это работает, но мне не нравится, что я должен пройти в внешнее свойство для каждого поля ввода, и мне не нравится асимметрия проверки проверки. Есть ли лучший способ сделать это?

ответ

1

Вы можете попробовать: ngModelController.$setValidity

app.directive('active', ['$parse', function ($parse) { 
     var tid; 
     return { 
      restrict: 'A', 
      require: '?ngModel', 
      scope: 
      { 
       ngModel: "=" 
      }, 

      link: function (scope, elem, attrs, ctrl) { 
       elem.bind('blur', function() 
       { 
        scope.$apply(function(){ 
         ctrl.$setValidity("active",true); 
        }); 
       }); 
       var timeout = attrs.active || 2000; 
       ctrl.$parsers.unshift(function(value) 
       { 
        ctrl.$setValidity("active",false); 
        console.log("adding class"); 

        if (tid) clearTimeout(tid); 

        tid = setTimeout(function() 
        { 
         ctrl.$setValidity("active",false); 
        }, timeout); 
        return value; 
       }) 


      } 
     }; 
    }]); 

1) Установка активной, как это: ctrl.$setValidity("active",true);.

2) Доступ из html следующим образом: f.e.$error.active.

3) Имейте в виду, что, когда мы используем эту функцию: ctrl.$setValidity("active",true); означает, что нет никакой ошибки с active =>f.e.$error.active == true (вид реверс текущую логику)

DEMO

Другим решением является просто добавить свойство прямо на ваш ngModelController: ctrl.active = false; и получите доступ к нему в html следующим образом: f.e.active. Но это решение не является хорошим ИМО, потому что оно может столкнуться с будущей версией углового, когда угловой решает создать новое свойство с тем же именем.

DEMO

+0

Я думал первого решения, но так как "активный" на самом деле просто информативный бит для стилизации, а не ошибка, помещая что-либо в то, что делает недействительной форму, не будет работать. Ваш второй ответ - это то, что я ищу; Я мог бы поклясться, что я это пробовал, не знаю, что я испортил. Я понимаю возможности столкновения имен, но кажется разумным, что должен быть способ для пользователей расширять элементы таким же образом, что и Angular внутри. Я поставлю на нем уникальный префикс. Благодаря! –

+0

@ Джолли Роджер: не нужно ругаться. Хорошего дня. Я рад, что это помогает. –

1

Чтобы построить на (второй) ответ @Khanh к, я обновил скрипку мой оригинал немного более точно соответствовать и удалить некоторые опечатки. Затем я использую экспоненциальное состояние для стилирования как текста справки, так и поля ввода соответствующим образом с помощью ng-класса.

Go forth and fiddle!

Для потомков, соответствующие биты HTML:

<form name="f"> 
    <div class="form-group" ng-class="{'has-error': !f.e.active && f.e.$invalid}"> 
     <label>Enter Email Address</label> 
     <input type="email" ng-class="{'active' : f.e.active}" class="form-control" name="e" ng-model="user.email" required autofocus active="1500" /> 
     <p class="help-block" ng-show="!f.e.active && f.e.$error.required">email is required</p> 
     <p class="help-block" ng-show="!f.e.active && f.e.$error.email">enter a valid email address</p> 
     <p class="help-block" ng-show="f.e.active">typing...</p> 
     <p class="help-block" ng-show="!f.e.active && f.$valid">ok!</p> 

    </div> 
</form> 

и JS:

app.directive('active', ['$parse', function ($parse) { 
     var tid; 
     return { 
      restrict: 'A', 
      require: '?ngModel', 

      // warning - this adds an "active" property to ctrl; consider prefixing to avoid future collisions 
      link: function (scope, elem, attrs, ctrl) { 
       elem.bind('blur', function() 
       { 
        ctrl.active = false; 
       }); 
       var timeout = attrs.active || 2000; 
       ctrl.$parsers.unshift(function(value) 
       { 
        ctrl.active = true; 
        if (tid) clearTimeout(tid); 

        tid = setTimeout(function() 
        { 
         scope.$apply(function(){ 
          ctrl.active = false; 
         }); 

        }, timeout); 
        return value; 
       }) 


      } 
     }; 
    }]); 
Смежные вопросы