При отправке формы в AngularJS и использовании функции запоминания пароля в браузере и при последующей попытке входа вы позволяете браузеру заполнить форму входа с именем пользователя и паролем, $scope
модель не будет изменена на основе автозаполнения.
Единственный грязный прием, который я нашел, - это использовать следующую директиву:
app.directive("xsInputSync", ["$timeout" , function($timeout) {
return {
restrict : "A",
require: "?ngModel",
link : function(scope, element, attrs, ngModel) {
$timeout(function() {
if (ngModel.$viewValue && ngModel.$viewValue !== element.val()) {
scope.apply(function() {
ngModel.$setViewValue(element.val());
});
}
console.log(scope);
console.log(ngModel.$name);
console.log(scope[ngModel.$name]);
}, 3000);
}
};
}]);
Проблема в том, что ngModel.$setViewValue(element.val());
не меняет ни модель, ни представление на основе element.val()
возвращаемого значения. Как я могу этого добиться?
javascript
mvvm
angularjs
Lucassp
источник
источник
Ответы:
По-видимому, это известная проблема с Angular и в настоящее время открыта.
Я не уверен, что вы могли бы здесь сделать, кроме какой-то работы, как вы пытаетесь. Похоже, ты на правильном пути. Мне не удалось заставить свой браузер попытаться запомнить пароль для вашего блока, поэтому я не уверен, что это сработает, но посмотрите:
Думаю, вам просто нужно немного упростить свой подход. Единственное, что я определенно рекомендую, - это проверить
ngModel.$pristine
и убедиться, что вы не перезаписываете ввод некорректного пользователя. Кроме того, 3 секунды, вероятно, слишком долго. Вам не нужно вызывать $ apply () в $ timeout, BTW, он должен автоматически поставить в очередь $ дайджест.Настоящая загвоздка: сможет ли ваш браузер превзойти Angular по производительности? А как насчет моего браузера?
Скорее всего, это война, в которой невозможно победить, поэтому Angular (или Knockout) не смог ее быстро решить. Нет никакой гарантии состояния данных во вводе во время первоначального выполнения директивы. Даже во время инициализации Angular ... Так что это сложная проблема.
источник
Вот решение, которое гораздо менее хакерское, чем другие представленные решения, и семантически правильное AngularJS: http://victorblog.com/2014/01/12/fixing-autocomplete-autofill-on-angularjs-form-submit/
Затем вы просто прикрепляете директиву к своей форме:
источник
Вам не нужно использовать a
$timeout
или что-то подобное. Вы можете использовать систему событий.Я думаю, что это более Angularish и не зависит от jQuery или перехвата пользовательских событий.
Например, в вашем обработчике отправки:
И тогда у вас может быть такая
autofill
директива:Наконец, ваш HTML будет таким:
источник
Больше не нужно взламывать! Angular dev tbosch создал полифилл, который запускает событие изменения, когда браузер меняет поля формы без запуска события изменения:
https://github.com/tbosch/autofill-event
На данный момент они не будут встраивать это в код Angular, поскольку это исправление ошибки для браузера, а также работает без Angular (например, для простых приложений jQuery).
«Полифилл будет проверять наличие изменений при загрузке документа, а также при оставлении ввода (только в той же форме). Однако вы можете запустить проверку вручную, если хотите.
В проекте есть как модульные, так и полуавтоматические тесты, поэтому у нас наконец-то есть место для сбора всех различных вариантов использования вместе с необходимыми настройками браузера.
Обратите внимание: этот полифилл работает с простыми приложениями AngularJS, с приложениями AngularJS / jQuery, но также и с простыми приложениями jQuery, которые не используют Angular ».
Его можно установить с помощью:
Добавьте скрипт
autofill-event.js
после jQuery или Angular на свою страницу.Это сделает следующее:
API (для запуска проверки вручную):
$el.checkAndTriggerAutoFillEvent()
: Выполнить проверку всех элементов DOM в данном элементе jQuery / jQLite.Как это устроено
Запомните все изменения элементов ввода пользователем (прослушивание событий изменения), а также JavaScript (путем перехвата $ el.val () для элементов jQuery / jQLite). Это измененное значение сохраняется в элементе в частной собственности.
Проверка элемента на автозаполнение: сравните текущее значение элемента с запомненным значением. Если он другой, инициируйте событие изменения.
зависимости
AngularJS или jQuery (работает с одним или обоими)
Дополнительная информация и источник на странице github .
Исходный выпуск Angular №1460 на Github можно прочитать здесь.
источник
ngModelOptions
в сочетании соautofill-event
средствами, которые теперь можно указать вchange
качестве одного изupdateOn
событий, чтобы убедиться, что ваша модель правильно синхронизирована.Грязный код, проверьте, исправлена ли проблема https://github.com/angular/angular.js/issues/1460#issuecomment-18572604, прежде чем использовать этот код. Эта директива запускает события при заполнении поля, а не только перед отправкой (это необходимо, если вам нужно обработать ввод перед отправкой)
источник
Похоже на четкое прямое решение. Не требуется jQuery.
ОБНОВИТЬ:
источник
$pristine
перед ее изменением, а затем после ее изменения сохранить ее$pristine
состояние. В противном случае вы обнаружите, что если форма загружается без данных автозаполнения, указанная выше директива все равно обновит модель и впоследствии сделает это,dirty
даже если элемент управления формы все еще должен считаться нетронутым. пример здесь, используя вашу директиву. Я закомментировал код, который хотел бы добавить к нему: jsfiddle.net/OACDesigns/L8Sja/4scope:true
должно бытьscope:{}
Решение 1 [Использование $ timeout]:
Директива:
HTML:
Решение 2 [Использование угловых событий]:
Ссылка: ответ Беко
Директива:
HTML:
Решение 3 [Использование вызовов метода ретрансляции]:
Директива:
HTML:
источник
model.$valid
Директива check in возвращает истину как до, так и после$setViewValue
, но элемент все еще сng-invalid
классомЧто ж, самый простой способ имитировать поведение браузера, поэтому, если есть проблема с событием изменения, просто запустите его самостоятельно. Намного проще.
Директива:
HTML:
Вы можете сделать несколько вариантов, например, поместить директиву в форму и запустить событие на всех входах с помощью класса .dirty при отправке формы.
источник
Это способ jQuery:
Это способ Angular:
HTML
источник
triggerHandler('input')
должно быть хорошо, если у вас нет полнофункционального jqueryВот еще один обходной путь, который менее хакерский, но требует дополнительного кода в контроллере.
HTML:
Директива (CoffeeScript):
контроллер:
источник
Это единственное решение, которое я нашел, которое позволило всем моим проверкам Angular работать так, как задумано, включая отключение / включение кнопки отправки. Устанавливается с беседкой и 1 тегом сценария. Bazinga!
https://github.com/tbosch/autofill-event
источник
У меня сработало изменение значения модели вместо использования функции тайм-аута.
Вот мой код:
источник
Однострочный обходной путь в обработчике отправки (требуется jQuery):
источник
Я заставляю $ setValue (val ()) отправить: (это работает без jQuery)
источник
Я новичок в Angularjs, но я нашел простое решение этой проблемы => Заставьте Angular переоценить выражение ... изменив его! (конечно, вам нужно запомнить начальное значение, чтобы вернуться в исходное состояние) Вот как это происходит в вашей функции контроллера для отправки формы:
где, конечно, значение, введенное при вводе пароля, было установлено Windows, а не пользователем.
источник
Вы можете попробовать этот код:
источник
Незначительная модификация этого ответа ( https://stackoverflow.com/a/14966711/3443828 ): используйте интервал $ вместо тайм-аута $, чтобы вам не приходилось гонять браузер.
источник
Это решение, которое я использовал в своих формах.
И шаблон формы будет
Таким образом, я смог запустить любые парсеры / средства форматирования, которые у меня есть на моей ng-модели, и сделать функцию отправки прозрачной.
источник
Решение без директив:
источник
Это простое исправление, которое работает во всех случаях, которые я тестировал в Firefox и Chrome. Обратите внимание, что с верхним ответом (директива без тайм-аута) у меня были проблемы с -
Это исправление, очевидно, очень глупое и хакерское, но оно работает в 100% случаев -
источник
$timeout
на,$interval
чтобы дать будущим разработчикам немного больше контекста и избавиться от происходящих там странно выглядящих рекурсивных вызововНи одно из этих решений не помогло моему варианту использования. У меня есть поля формы, которые используют ng-change для отслеживания изменений. Использование
$watch
не помогает, так как оно не запускается автозаполнением. Поскольку у меня нет кнопки отправки, нет простого способа запустить некоторые решения, и мне не удалось использовать интервалы.В итоге я отключил автозаполнение - не идеально, но гораздо менее запутанно для пользователя.
Нашел ответ здесь
источник
Если вы используете jQuery, вы можете сделать это при отправке формы:
HTML:
JS:
источник
Если вы хотите, чтобы это было просто, просто получите значение с помощью javascript
В вашем контроллере angular js:
var username = document.getElementById ('имя пользователя'). значение;
источник