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

时间:2012-08-08 21:42:49

标签: javascript jquery angularjs data-binding angular-ngmodel

这是我的HTML:

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

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

然而当我通过JQuery执行此操作时...

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

它不会更新模型。为什么呢?

10 个答案:

答案 0 :(得分:133)

Angular不知道这种变化。为此,您应致电$scope.$digest()或在$scope.$apply()内进行更改:

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

请参阅this以更好地了解脏检查

更新Here就是一个例子

答案 1 :(得分:27)

使用;

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

答案 2 :(得分:16)

我发现如果你不直接将变量放在范围内,它会更可靠地更新。

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

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

这对我有用。

答案 3 :(得分:4)

试试这个

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

答案 4 :(得分:3)

只需在函数末尾运行以下行:

$ scope。$ apply()

答案 5 :(得分:2)

无论在Angular范围之外发生什么,Angular都不会知道。

摘要周期从模型中进行更改 - &gt;控制器然后从控制器 - &gt;模型。

如果您需要查看最新的模型,则需要触发摘要周期

但是正在进行消化循环的可能性,所以我们需要检查并初始化循环。

最好始终执行安全申请。

       $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.
      });

答案 6 :(得分:1)

当AngularJS通过引用传递数组和对象时,它按值传递字符串,数字和布尔值。因此,您可以创建一个空对象,并使您的日期成为该对象的属性。这样,角度将检测模型变化。

在控制器中

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>

答案 7 :(得分:1)

您必须触发输入元素的更改事件,因为ng-model会侦听输入事件,并且范围将会更新。但是,常规jQuery触发器对我来说不起作用。但这就是魅力

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

以下无效

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

您可以阅读有关creating and dispatching synthetic events的更多信息。

答案 8 :(得分:0)

我已经为jQuery编写了这个小插件,它将使.val(value)的所有调用更新角元素(如果存在):

(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)更新现在应该很好。


缩小版:

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

示例:

&#13;
&#13;
// 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);
&#13;
<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>
&#13;
&#13;
&#13;


此答案是从my answer to another similar question逐字复制的。

答案 9 :(得分:0)

只需使用:

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

而不是:

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