Mettre à jour le modèle angulaire après avoir défini la valeur d'entrée avec jQuery
j'ai ce scénario simple:
élément D'entrée dont la valeur est changée par la méthode val() de jQuery.
j'essaie de mettre à jour le modèle angulaire avec la valeur que jQuery a définie. J'ai essayé d'écrire une simple directive, mais elle ne fait pas ce que je veux.
Voici la directive:
var myApp = angular.module('myApp', []);
myApp.directive('testChange', function() {
return function(scope, element, attrs) {
element.bind('change', function() {
console.log('value changed');
})
}
})
c'est la partie jQuery:
$(function(){
$('button').click(function(){
$('input').val('xxx');
})
})
et html:
<div ng-app="myApp">
<div ng-controller="MyCtrl">
<input test-change ng-model="foo" />
<span>{{foo}}</span>
</div>
</div>
<button>clickme</button>
voici le violon avec mon essai:
http://jsfiddle.net/U3pVM/743 /
quelqu'un peut-il m'indiquer la bonne direction?
10 réponses
ngModel écoute pour l'événement "input" , donc pour "corriger" votre code vous devez déclencher cet événement après avoir défini la valeur:
$('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
});
pour l'explication de ce comportement particulier, consultez la réponse que j'ai donnée il y a un certain temps: " comment les AngularJS saisissent-ils à l'interne des événements comme "onclick", "onchange"? "
Mais malheureusement, ce n'est pas le seul problème que vous avez. Comme l'a souligné avec autres commentaires postés, votre approche jQuery-centric est clairement erronée. Pour plus d'info jetez un oeil à ce post: Comment puis-je "penser en AngularJS" si j'ai une formation jQuery? ).
J'espère que c'est utile pour quelqu'un.
j'ai été incapable d'obtenir l'événement jQuery('#myInputElement').trigger('input')
pour être ramassé mon application angulaire.
j'ai cependant réussi à faire ramasser angular.element(jQuery('#myInputElement')).triggerHandler('input')
.
Je ne pense pas que jQuery soit nécessaire ici.
vous pouvez utiliser $ watch et ng-click à la place
<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>
dans votre contrôleur:
$scope.$watch('foo', function(newValue, oldValue) {
console.log(newValue);
console.log(oldValue);
});
vous devez utiliser le code suivant afin de mettre à jour la portée du modèle d'entrée spécifique comme suit
$('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;
});
});
la réponse acceptée qui déclenchait l'événement input
avec jQuery ne marchait pas pour moi. La création d'un événement et l'envoi avec JavaScript natif ont fait l'affaire.
$("input")[0].dispatchEvent(new Event("input", { bubbles: true }));
j'ai fait des modifications sur la seule initialisation du contrôleur en ajoutant l'auditeur sur le bouton d'action:
$(document).on('click', '#action-button', function () {
$timeout(function () {
angular.element($('#input')).triggerHandler('input');
});
});
d'Autres solutions n'ont pas fonctionné dans mon cas.
je sais qu'il est un peu tard pour répondre ici, mais peut-être que je peux en sauver quelques-uns une fois par jour.
j'ai fait face au même problème. Un modèle ne sera pas peuplé une fois que vous aurez mis à jour la valeur des entrées de jQuery. J'ai essayé d'utiliser des événements déclencheurs mais aucun résultat.
voici ce que j'ai fait qui pourrait sauver votre journée.
déclare une variable dans votre étiquette de script en HTML.
Comme:
<script>
var inputValue="";
// update that variable using your jQuery function with appropriate value, you want...
</script>
une fois que vous avez fait cela en utilisant ci-dessous le service d'angle.
"151920920 $" de la fenêtre
maintenant ci-dessous la fonction getData appelée à partir du même contrôleur scope vous donnera la valeur que vous voulez.
var myApp = angular.module('myApp', []);
app.controller('imageManagerCtrl',['$scope','$window',function($scope,$window) {
$scope.getData = function () {
console.log("Window value " + $window.inputValue);
}}]);
j'ai écrit ce petit plugin pour jQuery qui fera tous les appels à .val(value)
mettre à jour l'élément angulaire si présent:
(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);
Ecrivez juste ce script après jQuery et angular.les mises à jour de js et val(value)
devraient maintenant être agréables.
version Minifiée:
!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);
exemple:
// 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>
Si vous utilisez IE, vous devez utiliser: entrée.trigger("changement");
ajouter .change()
après avoir fixé la valeur.
exemple: ('id').val.('value').change();
aussi n'oubliez pas d'ajouter onchange
ou ng-change
étiquette en html