$watch срабатывает при потере фокуса

У меня есть тег textarea с подключенным к нему плагином jquery.nicescroll и ng-моделью.

<textarea id="paper" ng-model="paper"></textarea>

В моем коде я применяю $watch к этой переменной ng-model.

$scope.$watch("paper", onTextChange);

Все хорошо, за исключением того, что onTextChange срабатывает не только тогда, когда я что-то набираю, но и когда я щелкаю вне текстовой области, а также когда я переключаюсь на другую вкладку.

Как я могу предотвратить это, чтобы onTextChange срабатывал только при изменении текста, то есть когда я что-то ввожу или удаляю символы?

Демо с инструкциями: плункер


person kaytrance    schedule 19.01.2015    source источник
comment
вы используете часы для прослушивания изменений в бумаге, а не для события onTextChange.So, когда бумага меняется, она выполняет вашу функцию.   -  person changtung    schedule 19.01.2015
comment
нет, этим утверждением я говорю angular следить за изменениями переменной paper (в $scope) и запускать мою функцию onTextChanged(), если эта переменная изменяется. И поскольку он привязан к моей текстовой области через ng-модель, это событие должно запускаться, когда я что-то набираю в текстовой области. Который IS срабатывает, но не только когда я что-то набираю, но и когда я только прокручиваю вниз/вверх и нажимаю. Что странно.   -  person kaytrance    schedule 19.01.2015


Ответы (2)


вот исправление:

http://plnkr.co/edit/kycmUrthYU38Ukdz0jJG?p=preview

setTimeout( 
function() {
    $scope.$watch("paper", function(newtext, oldtext) {
      if (newtext !== oldtext) {
        onTextChange();
      }
    });
  }, 100)

Таким образом, проблема в том, что часы запускают функцию всякий раз, когда angularjs сообщает приложению о переваривании. Что вы сделали, так это приказали ему вызывать функцию «изменения» КАЖДЫЙ раз, когда вы должны были передать функцию проверки, чтобы проверить, произошло ли изменение. Речь идет о «наблюдении», а не о «отслеживании изменений» — аргумент функции должен видеть, нужно ли вам что-то делать.

Дополнительное примечание:

AngularJS настраивает наблюдатели за всевозможными вещами на различных элементах — здесь немного больше информации. Я считаю, что размытие соответствует ng-touched, который запускает дайджест and-what-triggers-d">Что добавляется в $scope.$$watchers по умолчанию в Angular? И что запускает $digests?

person Peter Ashwell    schedule 19.01.2015
comment
Я думаю, что если вы удалите setTimeout, метод onTextChange будет вызываться при загрузке события, поскольку поле extbox изначально пусто, и может быть небольшая задержка в тексте, заполняемом в текстовом поле. - person Ved; 19.01.2015

Плохая идея использовать setTimeout. Вместо этого вы можете использовать ng-model-options="{ getterSetter: true }" и написать метод для получения/установки значения (Modified get/set Plunk) и обрабатывать условие изменения текста в этом методе.

person Coder X    schedule 19.01.2015
comment
Я посмотрю на ваш планк, это что-то новое для меня. Спасибо - person kaytrance; 19.01.2015