AngularJS: запуск после дайджест-цикла с $ timeout (Safari vs chrome)

0

При заполнении формы я написал специальный код проверки, но мне нужно установить значение $timeout > 100 мс, чтобы заставить его работать, и мне любопытно узнать, почему.

Необходимые элементы формы следуют этому формату. Я добавляю класс "novalidate", если ввод неправильный: (замечайте, есть тонна этих элементов в форме)

<div class="dottedWrapper" ng-class="{novalidate:(newController.jobDescription.length == 0) && newController.formSubmitted}">

При отправке формы я проверяю, есть ли у каких-либо элементов класс "novalidate" и возврат.

 self.formSubmitted = true;

    $timeout(function () {

        // Validate! 
        if (document.getElementsByClassName("novalidate").length > 0) {
            return;
        }

        ... 

       }, 100); // MUST SET AT LEAST 100ms for it to work in safari

Однако это работает только в том случае, если я установил время примерно в 100 мс в Safari. В хроме, нужно только установить его на 1 мс.

Поправьте меня, если я ошибаюсь, но здесь мои мысли, и в виду, что я новичок в угловой:

  1. self.formSubmitted = true; я установил " self.formSubmitted = true; ". Это приводит к тому, что посредством двусторонней передачи данных происходит обновление для всех div, поскольку "formSubmitted" содержится внутри класса ng.

  2. Это делается через цикл дайджеста, что означает, что я не могу запустить " document.getElementsByClassName("novalidate") " сразу после того, как цикл дайджеста больше всего запускается один раз и обновляет все.

  3. Итак... Я использую $timeout, думая, что он будет пропускать текущий цикл дайджест, а затем перепрыгнуть в следующий цикл дайджеста. На этом этапе все элементы должны быть обновлены.

  • 1
    вам нужно использовать дом для хранения такой информации? если бы вы могли использовать JS Vars, вам не нужно было бы откладывать, что выглядит немного дерзко ...
  • 0
    Я мог бы сделать это, но есть тонна элементов ... С кодом, который у меня есть сейчас, это всего лишь одна строка для проверки.
Показать ещё 4 комментария
Теги:

2 ответа

1
Лучший ответ

Помимо ответа Pixelbits (с которым я полностью согласен), вы можете попробовать заменить $ timeout одним из следующих:

  • $evalAsync
  • $$postDigest

Где первый будет запускать новый цикл $ digest (точно так же, как $ timeout), а второй - нет.


Несмотря на это, я считаю, что лучше всего будет использовать встроенные директивы проверки input. И вместо проверки наличия класса novalidate в DOM, просто проверьте свойство <form>.$valid novalidate (<form> получает доступ к вашей области $, когда ему присваивается атрибут name).

Ваше мнение будет выглядеть примерно так;

<form name="myForm">
  <input ng-model="formData.jobDescription" ng-minlength="1">
</form>

И затем в вашем контроллере;

// var form = $scope.myForm; 
console.log(form.$valid); // true|false

Теперь приведенное выше предложение может не работать для вашего случая использования. Нам нужно больше узнать о вашей реализации, чтобы помочь вам в большей степени.

  • 0
    Большой! большое спасибо
2

Вы нарушаете шаблон MVC. Не надо - это плохая практика.

Почему бы вам просто не сделать:

if (self.jobDescription.length == 0 && self.formSubmitted)
    return;
  • 0
    Я мог бы сделать это, но есть тонна элементов ... С кодом, который у меня есть сейчас, это всего лишь одна строка для проверки.
  • 1
    @ BlackMouse, так почему бы просто не использовать встроенную проверку в angular? И вообще, вы пишете этот код для элемента ton, почему бы просто не переместить все это в одно место?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню