AngularJS:使用jQuery更改ng-model绑定时不会更新

这是我的HTML:

<input id="selectedDueDate" type="text" ng-model="selectedDate" /> 

当我input框中时,模型通过双向绑定机制进行更新。 甜。

但是,当我通过JQuery做到这一点…

 $('#selectedDueDate').val(dateText); 

它不更新模型。 为什么?

Angular不知道这个变化。 为此,您应该调用$scope.$digest()或者在$scope.$apply()内进行更改$scope.$apply()

 $scope.$apply(function() { // every changes goes here $('#selectedDueDate').val(dateText); }); 

看到这个更好地理解脏检查

更新 : 这是一个例子

只是使用;

 $('#selectedDueDate').val(dateText).trigger('input'); 

我发现,如果你不把这个variables直接放在范围上,它就会更可靠地更新。

尝试使用一些“dateObj.selectedDate”,并在控制器中将selectedDate添加到dateObj对象,如下所示:

 $scope.dateObj = {selectedDate: new Date()} 

这对我有效。

尝试这个

 var selectedDueDateField = document.getElementById("selectedDueDate"); var element = angular.element(selectedDueDateField); element.val('new value here'); element.triggerHandler('input'); 

只需在函数结尾处运行以下行:

$范围。$适用()

AngularJS通过引用传递数组和对象时传递string,数字和布尔值。 所以你可以创build一个空对象,并使你的date成为该对象的一个​​属性。 以这种方式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> 

我已经写了这个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); 

只要在jQuery和angular.js和val(value)更新应该现在打好后popup此脚本。


缩小版本:

 !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> 

无论AngularJS范围以外发生什么,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. }); 

您必须触发input元素的更改事件 ,因为ng-model侦听input事件,范围将被更新。 但是, 常规的jQuery触发器不适合我。 但是,这就像是一种魅力

 $("#myInput")[0].dispatchEvent(new Event("input", { bubbles: true })); //Works 

以下没有工作

 $("#myInput").trigger("change"); // Did't work for me 

您可以阅读关于创build和分派合成事件的更多信息。