AngularJS : ng-model binding not updating when changed with jQuery
这是我的HTML:
1 | <input id="selectedDueDate" type="text" ng-model="selectedDate" /> |
当我输入框中时,模型通过双向绑定机制进行更新。甜的。
但是,当我通过jquery执行此操作时…
1 | $('#selectedDueDate').val(dateText); |
它不会更新模型。为什么?
Angular不知道这种变化。For this you should call
1 2 3 4 | $scope.$apply(function() { // every changes goes here $('#selectedDueDate').val(dateText); }); |
看这个更好地理解脏检查
更新:下面是一个例子
只需使用;
1 | $('#selectedDueDate').val(dateText).trigger('input'); |
我发现,如果不将变量直接放在作用域上,它的更新会更可靠。
尝试使用一些"dateobj.selecteddate",然后在控制器中将selecteddate添加到dateobj对象中,如下所示:
1 | $scope.dateObj = {selectedDate: new Date()} |
这对我很有用。
试试这个
1 2 3 4 | var selectedDueDateField = document.getElementById("selectedDueDate"); var element = angular.element(selectedDueDateField); element.val('new value here'); element.triggerHandler('input'); |
只需在函数末尾运行以下行:
$Apple($)
不管角度范围之外发生什么,角度永远不会知道。
Digest Cycle将更改放在Model->Controller,然后放在Controller->Model。
如果需要查看最新的模型,则需要触发摘要循环。
但是有一个正在进行的消化循环的机会,所以我们需要检查并初始化这个循环。
最好始终进行安全应用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | $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. }); |
您必须触发输入元素的变更事件,因为ng模型监听输入事件,并且范围将被更新。但是,常规的jquery触发器不适用于我。但这才是真正的魅力所在
1 | $("#myInput")[0].dispatchEvent(new Event("input", { bubbles: true })); //Works |
跟踪不起作用
1 | $("#myInput").trigger("change"); // Did't work for me |
您可以阅读有关创建和分派合成事件的更多信息。
AngularJS传递字符串、数字和布尔值,同时通过引用传递数组和对象。因此,您可以创建一个空对象,并使日期成为该对象的属性。这样,角度将检测模型的变化。
在控制器中
1 2 3 | app.module('yourModule').controller('yourController',function($scope){ $scope.vm={selectedDate:''} }); |
在HTML中
1 | <input id="selectedDueDate" type="text" ng-model="vm.selectedDate" /> |
只需使用:
1 | $('#selectedDueDate').val(dateText).trigger('input'); |
而不是:
1 | $('#selectedDueDate').val(dateText); |
我已经为jquery编写了这个小插件,它将调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | (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和
缩小版本:
1 | !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); |
例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | // 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); |
1 2 3 4 5 6 | <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"> <input type="number" id="input" ng-model="input" ng-change="change()" /> <span>{{output}}</span> <button id="button">+</button> |
这个答案是从我对另一个类似问题的回答中逐字抄来的。