163

我有这个简单的场景:

输入元素的值被 jQuery 的 val() 方法改变。

我正在尝试使用 jQuery 设置的值更新角度模型。我试图写一个简单的指令,但它没有做我想要的。

这是指令:

var myApp = angular.module('myApp', []);
myApp.directive('testChange', function() {
    return function(scope, element, attrs) {        
        element.bind('change', function() {
            console.log('value changed');
        })
    }
})

这是 jQuery 部分:

$(function(){
    $('button').click(function(){
        $('input').val('xxx');
    })
})

和html:

<div ng-app="myApp">
    <div ng-controller="MyCtrl">
        <input test-change ng-model="foo" />
        <span>{{foo}}</span>
    </div>
</div>

<button>clickme</button>

这是我尝试的小提琴:http:
//jsfiddle.net/U3pVM/743/

有人可以指出我正确的方向吗?

4

12 回答 12

329

ngModel 侦听“输入”事件,因此要“修复”您的代码,您需要在设置值后触发该事件:

$('button').click(function(){
    var input = $('input');
    input.val('xxx');
    input.trigger('input'); // Use for Chrome/Firefox/Edge
    input.trigger('change'); // Use for Chrome/Firefox/Edge + IE11
});

对于这种特殊行为的解释,请查看我不久前给出的这个答案:“ AngularJS 如何在内部捕获像'onclick','onchange'这样的事件?


但不幸的是,这不是您遇到的唯一问题。正如其他帖子评论所指出的,您以 jQuery 为中心的方法是完全错误的。有关更多信息,请查看这篇文章:如果我有 jQuery 背景,我如何“在 AngularJS 中思考”?)。

于 2013-06-14T14:22:14.503 回答
61

希望这对某人有用。

我无法让jQuery('#myInputElement').trigger('input')事件被我的 Angular 应用程序拾取。

然而,我能够angular.element(jQuery('#myInputElement')).triggerHandler('input')被接走。

于 2014-05-24T23:52:24.103 回答
27

使用 jQuery触发input事件的公认答案对我不起作用。创建一个事件并使用本机 JavaScript 进行分派就可以了。

$("input")[0].dispatchEvent(new Event("input", { bubbles: true }));
于 2017-01-11T14:11:23.297 回答
22

我认为这里不需要 jQuery。

您可以改用$ watchng-click

<div ng-app="myApp">
  <div ng-controller="MyCtrl">
    <input test-change ng-model="foo" />
    <span>{{foo}}</span>

    <button ng-click=" foo= 'xxx' ">click me</button>
    <!-- this changes foo value, you can also call a function from your controller -->
  </div>
</div>

在您的控制器中:

$scope.$watch('foo', function(newValue, oldValue) {
  console.log(newValue);
  console.log(oldValue);
});
于 2013-06-14T14:44:27.217 回答
18

您必须使用以下代码来更新特定输入模型的范围,如下所示

$('button').on('click', function(){
    var newVal = $(this).data('val');
    $('select').val(newVal).change();

    var scope = angular.element($("select")).scope();
    scope.$apply(function(){
        scope.selectValue = newVal;
    });
});
于 2014-03-05T15:54:16.080 回答
7

我通过在操作按钮上添加侦听器仅对控制器初始化进行了修改:

$(document).on('click', '#action-button', function () {
        $timeout(function () {
             angular.element($('#input')).triggerHandler('input');
        });
});

其他解决方案在我的情况下不起作用。

于 2015-08-26T10:35:59.687 回答
4

我知道在这里回答有点晚了,但也许我可以节省一些时间。

我一直在处理同样的问题。一旦您从 jQuery 更新输入值,模型将不会填充。我尝试使用触发事件但没有结果。

这是我所做的,可以节省您的时间。

在 HTML 中的 script 标签内声明一个变量。

像:

<script>
 var inputValue="";

// update that variable using your jQuery function with appropriate value, you want...

</script>

一旦你通过使用下面的角度服务做到了这一点。

$窗口

现在,从同一控制器范围调用的 getData 函数将为您提供所需的值。

var myApp = angular.module('myApp', []);

app.controller('imageManagerCtrl',['$scope','$window',function($scope,$window) {

$scope.getData = function () {
    console.log("Window value " + $window.inputValue);
}}]);
于 2017-03-02T08:24:29.753 回答
3

我已经为 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)现在更新应该会很好。


缩小版:

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

于 2015-03-12T17:45:52.997 回答
2

如果您使用的是 IE,则必须使用: input.trigger("change");

于 2016-06-29T00:54:09.763 回答
2

.change()设置值后添加。

例子:('id').val.('value').change();

也不要忘记在 html 中添加onchangeng-change标记

于 2016-10-20T07:04:34.007 回答
0

我这样做是为了能够使用 Vanilla/jQuery 从外部更新 ngModel 的值:

function getScope(fieldElement) {
    var $scope = angular.element(fieldElement).scope();
    var nameScope;
    var name = fieldElement.getAttribute('name');
    if($scope) {
        if($scope.form) {
            nameScope = $scope.form[name];
        } else if($scope[name]) {
            nameScope = $scope[name];
        }
    }
    return nameScope;
}

function setScopeValue(fieldElement, newValue) {
    var $scope = getScope(fieldElement);
    if($scope) {
        $scope.$setViewValue(newValue);
        $scope.$validate();
        $scope.$render();
    }
}

setScopeValue(document.getElementById("fieldId"), "new value");
于 2019-07-11T23:09:21.653 回答
0

不是 OP 要求的,而是任何可能编写用户脚本的灵魂,该用户脚本通过输入字段并填写所需的详细信息。没有什么(完全)对我有用,但最终设法以这种方式完成了它:

var el = $('#sp_formfield_fw_ip');
el.val("some value");
angular.element(el).triggerHandler('focus');
angular.element(el).triggerHandler('input');
angular.element(el).triggerHandler('change');
angular.element(el).triggerHandler('blur');

打开开发人员工具,并检查input添加事件的字段。在那里我找到了所有这些(就我而言):focusinput和。changeblur

于 2020-09-01T07:05:41.280 回答