Обновить модель Angular после установки значения ввода с помощью jQuery
У меня есть такой простой сценарий:
Элемент ввода, значение которого изменяется с помощью метода jQuery val().
Я пытаюсь обновить модель angular со значением, заданным jQuery. Я попытался написать простую директиву, но это не делает то, что я хочу.
Здесь директива:
var myApp = angular.module('myApp', []);
myApp.directive('testChange', function() {
return function(scope, element, attrs) {
element.bind('change', function() {
console.log('value changed');
})
}
})
это часть jQuery:
$(function(){
$('button').click(function(){
$('input').val('xxx');
})
})
и html:
<div ng-app="myApp">
<div ng-controller="MyCtrl">
<input test-change ng-model="foo" />
<span>{{foo}}</span>
</div>
</div>
<button>clickme</button>
Вот скрипка с моей попыткой:
http://jsfiddle.net/U3pVM/743/
Кто-нибудь может указать мне в правильном направлении?
Ответы
Ответ 1
ngModel прослушивает событие "ввода", поэтому для "исправления" вашего кода вам необходимо запустить это событие после установки значения:
$('button').click(function(){
var input = $('input');
input.val('xxx');
input.trigger('input'); // Use for Chrome/Firefox/Edge
input.trigger('change'); // Use for Chrome/Firefox/Edge + IE11
});
Для объяснения этого конкретного поведения проверьте этот ответ, который я дал некоторое время назад: "Как AngularJS внутренне захватывает такие события, как "onclick" , "onchange" ?"
Но, к сожалению, это не единственная проблема, которая у вас есть. Как отмечалось в других комментариях к сообщениям, ваш подход, ориентированный на jQuery, совершенно неправильный. Для получения дополнительной информации см. Сообщение: Как мне "думать в AngularJS" , если у меня есть фон jQuery?).
Ответ 2
Надеюсь, это полезно для кого-то.
Мне не удалось получить событие jQuery('#myInputElement').trigger('input')
для моего приложения angular.
Я мог, однако, получить angular.element(jQuery('#myInputElement')).triggerHandler('input')
.
Ответ 3
Я не думаю, что здесь требуется jQuery.
Вместо $watch и ng-click можно использовать
<div ng-app="myApp">
<div ng-controller="MyCtrl">
<input test-change ng-model="foo" />
<span>{{foo}}</span>
<button ng-click=" foo= 'xxx' ">click me</button>
<!-- this changes foo value, you can also call a function from your controller -->
</div>
</div>
В вашем контроллере:
$scope.$watch('foo', function(newValue, oldValue) {
console.log(newValue);
console.log(oldValue);
});
Ответ 4
Вы должны использовать следующий код, чтобы обновить область конкретной модели ввода следующим образом
$('button').on('click', function(){
var newVal = $(this).data('val');
$('select').val(newVal).change();
var scope = angular.element($("select")).scope();
scope.$apply(function(){
scope.selectValue = newVal;
});
});
Ответ 5
Принятый ответ, который запускал событие input
с jQuery, не работал у меня. Создание события и отправка с помощью встроенного JavaScript сделали трюк.
$("input")[0].dispatchEvent(new Event("input", { bubbles: true }));
Ответ 6
Я вносил изменения только при инициализации контроллера, добавляя кнопку прослушивания на кнопку действия:
$(document).on('click', '#action-button', function () {
$timeout(function () {
angular.element($('#input')).triggerHandler('input');
});
});
Другие решения в моем случае не работали.
Ответ 7
Я знаю, что это немного поздно, чтобы ответить здесь, но, возможно, я смогу сэкономить один раз в день.
Я имел дело с той же проблемой. Модель не будет заполняться после обновления значения ввода из jQuery. Я пробовал использовать триггерные события, но никаких результатов.
Вот что я сделал, что может спасти ваш день.
Объявить переменную в теге script в HTML.
Как
<script>
var inputValue="";
// update that variable using your jQuery function with appropriate value, you want...
</script>
Как только вы сделали это, используя ниже сервис angular.
$окно
Теперь ниже функция getData, вызванная из той же области контроллера, даст вам нужное значение.
var myApp = angular.module('myApp', []);
app.controller('imageManagerCtrl',['$scope','$window',function($scope,$window) {
$scope.getData = function () {
console.log("Window value " + $window.inputValue);
}}]);
Ответ 8
Я написал этот маленький плагин для 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>
Ответ 9
Если вы используете IE, вам нужно использовать: input.trigger( "change" );
Ответ 10
добавить .change()
после установки значения.
Пример: ('id').val.('value').change();
также не забудьте добавить тег onchange
или ng-change
в html
Ответ 11
Я сделал это, чтобы иметь возможность обновить значение ngModel извне с помощью Vanilla/jQuery:
function getScope(fieldElement) {
var $scope = angular.element(fieldElement).scope();
var nameScope;
var name = fieldElement.getAttribute('name');
if($scope) {
if($scope.form) {
nameScope = $scope.form[name];
} else if($scope[name]) {
nameScope = $scope[name];
}
}
return nameScope;
}
function setScopeValue(fieldElement, newValue) {
var $scope = getScope(fieldElement);
if($scope) {
$scope.$setViewValue(newValue);
$scope.$validate();
$scope.$render();
}
}
setScopeValue(document.getElementById("fieldId"), "new value");