Javascript AngularJS:使用 jQuery 更改时,ng-model 绑定不会更新
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11873627/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
AngularJS : ng-model binding not updating when changed with jQuery
提问by Greg
This is my HTML:
这是我的 HTML:
<input id="selectedDueDate" type="text" ng-model="selectedDate" />
When I type into the box, the model is updated via the 2-way-binding mechanism. Sweet.
当我在框中键入内容时,模型将通过 2 路绑定机制进行更新。甜的。
Howeverwhen I do this via JQuery...
但是,当我通过 JQuery 执行此操作时...
$('#selectedDueDate').val(dateText);
It doesn't update the model. Why?
它不会更新模型。为什么?
回答by Renan Tomal Fernandes
Angular doesn't know about that change. For this you should call $scope.$digest()
or make the change inside of $scope.$apply()
:
Angular 不知道这种变化。为此,您应该调用$scope.$digest()
或在内部进行更改$scope.$apply()
:
$scope.$apply(function() {
// every changes goes here
$('#selectedDueDate').val(dateText);
});
See thisto better understand dirty-checking
看到这个以更好地理解脏检查
UPDATE: Hereis an example
更新:这是一个例子
回答by Jan Kuri
Just use;
只需使用;
$('#selectedDueDate').val(dateText).trigger('input');
回答by Ben Taliadoros
I have found that if you don't put the variable directly against the scope it updates more reliably.
我发现如果你不直接将变量放在作用域上,它会更可靠地更新。
Try using some "dateObj.selectedDate" and in the controller add the selectedDate to a dateObj object as so:
尝试使用一些“dateObj.selectedDate”并在控制器中将 selectedDate 添加到 dateObj 对象,如下所示:
$scope.dateObj = {selectedDate: new Date()}
This worked for me.
这对我有用。
回答by Ray
Try this
尝试这个
var selectedDueDateField = document.getElementById("selectedDueDate");
var element = angular.element(selectedDueDateField);
element.val('new value here');
element.triggerHandler('input');
回答by Rohan M Nabar
Just run the following line at the end of your function:
只需在函数末尾运行以下行:
$scope.$apply()
$scope.$apply()
回答by Rajendra kumar Vankadari
Whatever happens outside the Scope of Angular, Angular will never know that.
无论在 Angular 的 Scope 之外发生什么,Angular 永远不会知道。
Digest cycle put the changes from the model -> controller and then from controller -> model.
摘要循环将更改从模型 -> 控制器,然后从控制器 -> 模型。
If you need to see the latest Model, you need to trigger the digest cycle
如果需要查看最新的Model,需要触发digest循环
But there is a chance of a digest cycle in progress, so we need to check and init the cycle.
但是有可能正在进行一个消化循环,所以我们需要检查并初始化循环。
Preferably, always perform a safe apply.
最好始终执行安全应用。
$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.
});
回答by Himanshu Mittal
AngularJS pass string, numbers and booleans by value while it passes arrays and objects by reference. So you can create an empty object and make your date a property of that object. In that way angular will detect model changes.
AngularJS 按值传递字符串、数字和布尔值,同时按引用传递数组和对象。因此,您可以创建一个空对象并使您的日期成为该对象的属性。通过这种方式,angular 将检测模型变化。
In controller
在控制器中
app.module('yourModule').controller('yourController',function($scope){
$scope.vm={selectedDate:''}
});
In html
在 html 中
<div ng-controller="yourController">
<input id="selectedDueDate" type="text" ng-model="vm.selectedDate" />
</div>
回答by Hari Das
You have to trigger the change eventof the input element because ng-model listens to input events and the scope will be updated. However, the regular jQuery trigger didn't workfor me. But here is what works like a charm
您必须触发输入元素的更改事件,因为 ng-model 会侦听输入事件并且范围将被更新。但是,常规的 jQuery 触发器对我不起作用。但这是一种魅力
$("#myInput")[0].dispatchEvent(new Event("input", { bubbles: true })); //Works
Following didn't work
关注无效
$("#myInput").trigger("change"); // Did't work for me
You can read more about creating and dispatching synthetic events.
您可以阅读有关创建和分派合成事件的更多信息。
回答by Wekerle Tibor
Just use:
只需使用:
$('#selectedDueDate').val(dateText).trigger('input');
instead of:
代替:
$('#selectedDueDate').val(dateText);
回答by dav_i
I've written this little plugin for jQuery which will make all calls to .val(value)
update the angular element if present:
我已经为 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);
Just pop this script in after jQuery and angular.js and val(value)
updates should now play nice.
只需在 jQuery 和 angular.js 之后弹出这个脚本,val(value)
更新现在应该可以正常运行了。
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>
This answer was copied verbatim from my answer to another similar question.
这个答案是从我对另一个类似问题的回答中逐字复制的。