Хобрук: Ваш путь к мастерству в программировании

Проверка Angularjs ведет себя по-разному для 1.3.0 и 1.2.6.

Я хочу создать пользовательскую директиву, которая отображается как элемент типа ввода. Директива должна повторно использовать структуру проверки angularjs. Ниже приведена директива custom-input в действии, которую я создал:

<!doctype html>
<html ng-app="validationApp">
<body>
  <div class="container" ng-controller="ValidationController as validationController">
    <form name="myForm">
        {{employee | json}}
    <custom-input ng-required="true" ng-model="employee.name" name="employee.name" id="employeeName" ng-pattern="/^[0-9]{1,7}$/"/></custom-input>
    <span ng-show="myForm['employee.name'].$error.required">This is a required field</span>
    <span ng-show="myForm['employee.name'].$error.pattern">This is a invalid field</span>
    </form>
  </div>
  <script type="text/ng-template" id="/templates/customInput.html">
    <div>
        <input type="text" name="{{name}}" ng-model="newInput" id="{{id}}">
    </div>
  </script>
  <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.6/angular.js"></script>
</body>

</html>

Соответствующий этому javascript:

angular.module('validationApp', [])
.controller("ValidationController", function(){

})
.directive("customInput", function(){
    return {
        restrict: "E",
        require : "ngModel",
        replace: "true",
        templateUrl : "/templates/customInput.html",
        scope : {
            id : "@", //bind id to scope
            name : "@" //bind name to scope
        },
        link: function(scope, element, attrs, ngModelCtrl){
            //When newInput is updated, update the model of original input
             scope.$watch('newInput', function(newValue){
                ngModelCtrl.$setViewValue(newValue);
            });

            //On first load, get the initial value of original input's model and assign it to new input's model
            ngModelCtrl.$render = function(){
                var viewValue = ngModelCtrl.$viewValue;
                if(viewValue){
                    scope.newInput = viewValue;
                }
            }
        }
    }
});

Я пытаюсь применить проверку ng-required и ng-pattern к этому пользовательскому вводу. Я сталкиваюсь с двумя проблемами:

  1. В angularjs 1.2.6 я могу запустить проверку ng-required в custom-input, но в 1.3.0 проверка не запускается.
  2. Я не могу запустить проверку ng-pattern в обеих версиях.

Насколько я понимаю, $setViewValue из ngModelController будут запускать все проверки. Вышеупомянутый пример — надуманный пример, мой фактический вариант использования — создать пользовательскую директиву, которая отображает три поля ввода для SSN.

Ниже приведена ссылка на плункер для 1.2.6 и 1.3.0 соответственно:

Angularjs 1.2.6 Angularjs 1.3.0


  • replace: параметр true теперь устарел. Избегайте его использования. 18.10.2014
  • использовать нг-форму. form не работает с вложенными формами. 20.10.2014
  • Я не понял тебя. Я не вижу здесь вложенных форм! 20.10.2014

Ответы:


1
  1. Чтобы ng-required работало, не используйте одно и то же имя на входе внутренней формы ввода. Похоже, что в Angular 1.3 это переопределяет зарегистрированный ngModelController, прикрепленный к вашему custom-input.

    Таким образом, шаблон для директивы может быть

    <div>
      <input type="text" ng-model="newInput" id="{{id}}">
    </div>
    

    Это можно увидеть на странице http://plnkr.co/edit/TqMkxV?p=preview.

    (Кроме того, не уверен, зачем вам здесь нужен идентификатор...)

  2. Я думаю (но не уверен) в 1.2.6 ngPattern работает только с input элементами, а в 1.3 это отдельная директива, которая интегрируется с ngModel. Кроме того, чтобы заставить его работать в 1.3

Изменить после комментариев:

  1. Если вы хотите, чтобы имя отображалось во внутренней директиве и совпадало с именем родительского элемента (например, для отправки с использованием стандартного полностраничного POST на сервер), вы можете обернуть его в именованный файл ngForm. Это гарантирует, что его контроллер не переопределит родительский в области видимости.

    <div>
      <div ng-form name="customInput">
        <input type="text" ng-model="newInput" id="{{id}}" name="{{name}}">
      </div>
    </div>
    

    Это можно увидеть по адресу http://plnkr.co/edit/Jrk63A?p=preview

21.10.2014

2

В изолирующей области внутри директивы попробуйте связать ее, используя '=' вместо '@'

С @ вам нужно будет использовать attr.$observe('title', function(value) { ... }), если вам нужно использовать значение в вашей функции ссылки. Например, if(scope.title == "...") не будет работать так, как вы ожидаете. Обратите внимание, что это означает, что вы можете получить доступ к этому атрибуту только асинхронно. Вам не нужно использовать $observe(), если вы используете значение только в шаблоне. Например, шаблон: '{{title}}'.

С = вам не нужно использовать $observe.

(ОТ В чем разница между '@' и '=' в области действия директивы в AngularJS?)

angular.module('validationApp', [])
.controller("ValidationController", function(){

})
.directive("customInput", function(){
return {
    restrict: "E",
    require : "ngModel",
    replace: "true",
    templateUrl : "/templates/customInput.html",
    scope : {
        id : "=", //bind id to scope
        name : "=" //bind name to scope
    },
    link: function(scope, element, attrs, ngModelCtrl){
        //When newInput is updated, update the model of original input
         scope.$watch('newInput', function(newValue){
            ngModelCtrl.$setViewValue(newValue);
        });

        //On first load, get the initial value of original input's model and assign it to new input's model
        ngModelCtrl.$render = function(){
            var viewValue = ngModelCtrl.$viewValue;
            if(viewValue){
                scope.newInput = viewValue;
            }
        }
    }
}
});
20.10.2014
  • Я не уверен, почему изолированная область должна вызывать здесь проблему. Я бы не хотел, чтобы моя пользовательская модель ввода отображалась в родительской области. В случае, если этот пользовательский ввод используется несколько раз, они будут конфликтовать в области видимости. Кроме того, я хотел бы знать, почему существует разница между 1.2.6 и 1.3.0? И ng-pattern тоже не увольняют. Я предполагаю, что ng-шаблон будет срабатывать только для тега input, а не для custom-tag. 21.10.2014
  • @Vaibhav Если это так, привяжите его, используя '=' вместо '@' 21.10.2014
  • Спасибо за ответ. Я попытался включить ваше предложение. Пожалуйста, обратитесь к планкеру здесь http://embed.plnkr.co/FwQFhu/preview. Это по-прежнему не решает проблему с 1.3.0 по сравнению с 1.2.6. Не могли бы вы поделиться со мной фрагментом работающего кода на случай, если я не смогу понять ваше предложение. 21.10.2014

  • 3

    Согласно документу (https://docs.angularjs.org/guide/migration), строка регулярного выражения используется в качестве значения для шаблона ng в angular 1.2. Напротив, объект регулярного выражения используется в версии 1.3.

    // 1.2
    $scope.exp = '/abc/i'; //string
    
    <input ng-pattern="{{exp}}" ...
    
    
    // 1.3
    $scope.exp = /abc/i; //regexp object
    
    <input ng-pattern="exp" ...
    

    Вот мой пример пользовательской директивы ввода

    угловой 1.2.16:

    http://jsfiddle.net/miyukiw/m03f2ymt/4/

    угловой 1.3.5:

    http://jsfiddle.net/miyukiw/9d64oa1m/4/

    Я надеюсь, что это поможет.

    19.02.2015
    Новые материалы

    Основы принципов S.O.L.I.D, Javascript, Git и NoSQL
    каковы принципы S.O.L.I.D? Принципы SOLID призваны помочь разработчикам создавать надежные, удобные в сопровождении приложения. мы видим пять ключевых принципов. Принципы SOLID были разработаны..

    Как настроить Selenium в проекте Angular
    Угловой | Селен Как настроить Selenium в проекте Angular Держите свое приложение Angular и тесты Selenium в одной рабочей области и запускайте их с помощью Mocha. В этой статье мы..

    Аргументы прогрессивного улучшения почти всегда упускают суть
    В наши дни в кругах веб-разработчиков много болтают о Progressive Enhancement — PE, но на самом деле почти все аргументы с обеих сторон упускают самую фундаментальную причину, по которой PE..

    Введение в Джанго Фреймворк
    Схема «работать умно, а не усердно» В этой и последующих статьях я познакомлю вас с тем, что такое фреймворк Django и как создать свое первое приложение с помощью простых и понятных шагов, а..

    Настольный ПК как «одно кольцо, чтобы править всеми» домашних компьютеров
    Вид после 9 месяцев использования С настольных компьютеров все началось, но в какой-то момент они стали «серверами», и мы все перешли на ноутбуки. В прошлом году я столкнулся с идеей настольных..

    Расширенные методы безопасности для VueJS: реализация аутентификации без пароля
    Руководство, которое поможет вам создавать безопасные приложения в долгосрочной перспективе Безопасность приложений часто упускается из виду в процессе разработки, потому что основная..

    стройный-i18следующий
    Представляем стройную оболочку для i18next. Эта библиотека, основанная на i18next, заключает экземпляр i18next в хранилище svelte и отслеживает события i18next, такие как languageChanged,..