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

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 $scope.$digest() or make the change inside of $scope.$apply():

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编写了这个小插件,它将调用.val(value)更新angular元素(如果存在的话):

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和val(value)更新后弹出这个脚本,现在就可以了。

缩小版本:

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>

这个答案是从我对另一个类似问题的回答中逐字抄来的。