可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have this simple scenario:
Input element which value is changed by jQuery\'s val() method.
I am trying to update the angular model with the value that jQuery set. I tried to write a simple directive, but it\'s not doing what I want.
Here\'s the directive:
var myApp = angular.module(\'myApp\', []);
myApp.directive(\'testChange\', function() {
return function(scope, element, attrs) {
element.bind(\'change\', function() {
console.log(\'value changed\');
})
}
})
this is the jQuery part:
$(function(){
$(\'button\').click(function(){
$(\'input\').val(\'xxx\');
})
})
and html:
<div ng-app=\"myApp\">
<div ng-controller=\"MyCtrl\">
<input test-change ng-model=\"foo\" />
<span>{{foo}}</span>
</div>
</div>
<button>clickme</button>
Here is the fiddle with my try:
http://jsfiddle.net/U3pVM/743/
Can someone please point me in the right direction?
回答1:
ngModel listens for \"input\" event, so to \"fix\" your code you\'d need to trigger that event after setting the value:
$(\'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
});
For the explanation of this particular behaviour check out this answer that I gave a while ago: \"How does AngularJS internally catch events like \'onclick\', \'onchange\'?\"
But unfortunately, this is not the only problem you have. As pointed out with other post comments, your jQuery-centric approach is plain wrong. For more info take a look at this post: How do I “think in AngularJS” if I have a jQuery background?).
回答2:
Hope this is useful for someone.
I was unable to get the jQuery(\'#myInputElement\').trigger(\'input\')
event to be picked up my angular app.
I was however, able to get angular.element(jQuery(\'#myInputElement\')).triggerHandler(\'input\')
to be picked up.
回答3:
I don\'t think jQuery is required here.
You can use $watch and ng-click instead
<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>
In your controller :
$scope.$watch(\'foo\', function(newValue, oldValue) {
console.log(newValue);
console.log(oldValue);
});
回答4:
You have to use the following code in order to update the scope of the specific input model as follows
$(\'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:
The accepted answer which was triggering input
event with jQuery didn\'t work for me. Creating an event and dispatching with native JavaScript did the trick.
$(\"input\")[0].dispatchEvent(new Event(\"input\", { bubbles: true }));
回答6:
I made modifications on only controller initialization by adding listener on action button:
$(document).on(\'click\', \'#action-button\', function () {
$timeout(function () {
angular.element($(\'#input\')).triggerHandler(\'input\');
});
});
Other solutions did not work in my case.
回答7:
I know it\'s a bit late to answer here but maybe I may save some once\'s day.
I have been dealing with the same problem. A model will not populate once you update the value of input from jQuery. I tried using trigger events but no result.
Here is what I did that may save your day.
Declare a variable within your script tag in HTML.
Like:
<script>
var inputValue=\"\";
// update that variable using your jQuery function with appropriate value, you want...
</script>
Once you did that by using below service of angular.
$window
Now below getData function called from the same controller scope will give you the value you want.
var myApp = angular.module(\'myApp\', []);
app.controller(\'imageManagerCtrl\',[\'$scope\',\'$window\',function($scope,$window) {
$scope.getData = function () {
console.log(\"Window value \" + $window.inputValue);
}}]);
回答8:
I\'ve written this little plugin for jQuery which will make all calls to .val(value)
update the angular element if present:
(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);
Just pop this script in after jQuery and angular.js and val(value)
updates should now play nice.
Minified version:
!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);
Example:
// 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:
If you are using IE, you have to use: input.trigger(\"change\");
回答10:
add .change()
after setting the value.
example:(\'id\').val.(\'value\').change();
also don\'t forget to add onchange
or ng-change
tag in html