AngularJS: привязка ng-модели не обновляется при изменении с помощью jQuery
Это мой HTML:
<input id="selectedDueDate" type="text" ng-model="selectedDate" />
Когда я ввожу в поле, модель обновляется через механизм двусторонней привязки. Сладкое.
Однако, когда я делаю это через JQuery...
$('#selectedDueDate').val(dateText);
Он не обновляет модель. Почему?
Ответы
Ответ 1
Angular не знает об этом изменении. Для этого вы должны вызвать $scope.$digest()
или внести изменения внутри $scope.$apply()
:
$scope.$apply(function() {
// every changes goes here
$('#selectedDueDate').val(dateText);
});
См. этот, чтобы лучше понять грязную проверку
UPDATE: Здесь приведен пример
Ответ 2
Просто используйте;
$('#selectedDueDate').val(dateText).trigger('input');
Ответ 3
Я обнаружил, что если вы не поместите переменную непосредственно в область, которую она обновляет более надежно.
Попробуйте использовать некоторые "dateObj.selectedDate", а в контроллере добавьте selectedDate к объекту dateObj так:
$scope.dateObj = {selectedDate: new Date()}
Это сработало для меня.
Ответ 4
Попробуйте это
var selectedDueDateField = document.getElementById("selectedDueDate");
var element = angular.element(selectedDueDateField);
element.val('new value here');
element.triggerHandler('input');
Ответ 5
Что бы ни происходило за пределами области 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.
});
Ответ 6
Просто запустите следующую строку в конце вашей функции:
$scope. $apply()
Ответ 7
AngularJS передает строку, числа и логические значения по значению при передаче массивов и объектов по ссылке. Таким образом, вы можете создать пустой объект и сделать свою дату свойством этого объекта. Таким образом, angular обнаружит изменения модели.
В контроллере
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>
Ответ 8
Вам нужно вызвать событие изменения элемента ввода, потому что ng-model прослушивает входные события и область будет обновлена. Однако обычный jQuery-триггер не работал для меня. Но вот что работает как шарм
$("#myInput")[0].dispatchEvent(new Event("input", { bubbles: true })); //Works
Следующее не работает
$("#myInput").trigger("change"); // Did't work for me
Вы можете больше узнать о создании и отправке синтетических событий.
Ответ 9
Я написал этот маленький плагин для jQuery, который сделает все вызовы .val(value)
обновленным элементом angular, если он есть:
(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);
Просто введите этот script в после jQuery и angular.js и val(value)
обновления теперь должны играть хорошо.
Минимальная версия:
!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>