it-roy-ru.com

AngularJS: привязка ng-модели не обновляется при изменении с помощью jQuery

Это мой HTML:

<input id="selectedDueDate" type="text" ng-model="selectedDate" />

Когда я набираю текст в поле, модель обновляется с помощью механизма двусторонней привязки. Милая.

Однако когда я делаю это через JQuery ...

$('#selectedDueDate').val(dateText);

Это не обновляет модель. Зачем?

98
Greg

Angular не знает об этом изменении. Для этого вам следует вызвать $scope.$digest() или внести изменения внутри $scope.$apply():

$scope.$apply(function() { 
   // every changes goes here
   $('#selectedDueDate').val(dateText); 
});

Смотрите это чтобы лучше понять грязная проверка

UPDATE: Здесь это пример

131
Renan Tomal Fernandes

Просто используйте; 

$('#selectedDueDate').val(dateText).trigger('input');
27
Jan Kuri

Я обнаружил, что если вы не поместите переменную непосредственно в область видимости, она будет обновляться более надежно.

Попробуйте использовать некоторую дату dateObj.selectedDate и в контроллере добавьте selectedDate к объекту dateObj следующим образом:

$scope.dateObj = {selectedDate: new Date()}

Это сработало для меня.

16
Ben Taliadoros

Попробуй это

var selectedDueDateField = document.getElementById("selectedDueDate");
var element = angular.element(selectedDueDateField);
element.val('new value here');
element.triggerHandler('input');
4
Ray

Просто запустите следующую строку в конце вашей функции: 

$ Сфера. $ Применять () 

2
Rohan M Nabar

Что бы ни происходило вне Сфера Angular, Angular никогда не узнает этого. 

Цикл дайджеста помещает изменения из модели -> контроллер, а затем из контроллера -> модель. 

Если вам нужно увидеть последнюю модель, вам нужно запустить цикл дайджеста 

Но существует вероятность того, что цикл дайджеста продолжается, поэтому нам нужно проверить и запустить цикл.

Желательно всегда выполнять безопасное применение.

       $scope.safeApply = function(fn) {
            if (this.$root) {
                var phase = this.$root.$$phase;
                if (phase == '$apply' || phase == '$digest') {
                    if (fn && (typeof (fn) === 'function')) {
                        fn();
                    }
                } else {
                    this.$apply(fn);
                }
            }
        };


      $scope.safeApply(function(){
          // your function here.
      });
2
Rajendra kumar Vankadari

Вы должны вызвать событие change элемента input, потому что ng-model прослушивает события ввода, и область действия будет обновлена. Тем не менее, обычный триггер _Query не работал для меня. Но вот что работает как шарм

$("#myInput")[0].dispatchEvent(new Event("input", { bubbles: true })); //Works

Подписка не сработала

$("#myInput").trigger("change"); // Did't work for me

Вы можете прочитать больше о создание и рассылка синтетических событий .

1
Hari Das

AngularJS передает строку, числа и логические значения по значению, а массивы и объекты - по ссылке. Таким образом, вы можете создать пустой объект и сделать вашу дату свойством этого объекта. Таким образом, угловая будет обнаруживать изменения модели.

В контроллере

app.module('yourModule').controller('yourController',function($scope){
$scope.vm={selectedDate:''}
});

В HTML

<div ng-controller="yourController">
<input id="selectedDueDate" type="text" ng-model="vm.selectedDate" />
</div>
1
Himanshu Mittal

Просто используйте:

$('#selectedDueDate').val(dateText).trigger('input');

вместо:

$('#selectedDueDate').val(dateText);
0
Wekerle Tibor

Я написал этот небольшой плагин для jQuery, который будет делать все вызовы .val(value) обновлять угловой элемент, если он присутствует:

(function($, ng) {
  'use strict';

  var $val = $.fn.val; // save original jQuery function

  // override jQuery function
  $.fn.val = function (value) {
    // if getter, just return original
    if (!arguments.length) {
      return $val.call(this);
    }

    // get result of original function
    var result = $val.call(this, value);

    // trigger angular input (this[0] is the DOM object)
    ng.element(this[0]).triggerHandler('input');

    // return the original result
    return result; 
  }
})(window.jQuery, window.angular);

Просто вставьте этот скрипт после того, как обновления jQuery и angular.js и val(value) теперь должны играть в Nice.


Минимизированная версия:

!function(n,t){"use strict";var r=n.fn.val;n.fn.val=function(n){if(!arguments.length)return r.call(this);var e=r.call(this,n);return t.element(this[0]).triggerHandler("input"),e}}(window.jQuery,window.angular);

Пример:

// the function
(function($, ng) {
  'use strict';
  
  var $val = $.fn.val;
  
  $.fn.val = function (value) {
    if (!arguments.length) {
      return $val.call(this);
    }
    
    var result = $val.call(this, value);
    
    ng.element(this[0]).triggerHandler('input');
    
    return result;
    
  }
})(window.jQuery, window.angular);

(function(ng){ 
  ng.module('example', [])
    .controller('ExampleController', function($scope) {
      $scope.output = "output";
      
      $scope.change = function() {
        $scope.output = "" + $scope.input;
      }
    });
})(window.angular);

(function($){  
  $(function() {
    var button = $('#button');
  
    if (button.length)
      console.log('hello, button');
    
    button.click(function() {
      var input = $('#input');
      
      var value = parseInt(input.val());
      value = isNaN(value) ? 0 : value;
      
      input.val(value + 1);
    });
  });
})(window.jQuery);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div ng-app="example" ng-controller="ExampleController">
  <input type="number" id="input" ng-model="input" ng-change="change()" />
  <span>{{output}}</span>
  <button id="button">+</button>
</div>


Этот ответ был дословно скопирован из мой ответ на другой похожий вопрос .

0
dav_i