使用jquery element.val()时,ng-model没有更新

这里有PLUNKR的例子

我正在使用某种版本的jquery autocomplete作为angularjs direcitve。 当jquery使用element.val()更新输入的值时,在下一个摘要(我猜)之后才会注意到更改。

我的第一个想法是使用$timeoutng-model post digest执行操作,但是你可以看到它没有帮助。

我的第二种方法是覆盖元素的val函数来触发input事件,但我还没有设法让它工作。

尝试从自动完成列表中选择一个值,您将看到上面的ng-model没有更新。

UPDATE

谢谢你的回复。 我不知道onSelect选项。

这是基于您的建议的代码

 // clone user provided options scope.options = _.extend({}, scope.AutoCompleteOptions()); // Wrap onSelect - Force update before manipulation on ng-model var fn = _.has(scope.AutoCompleteOptions(), 'onSelect') ? scope.AutoCompleteOptions().onSelect : _.noop; scope.options.onSelect = function () { ngModelCtrl.$setViewValue(element.val()); scope.$apply(fn); }; scope.autocomplete = $(element).autocomplete(scope.options); 

这样我保持指令的界面,同时保证ng-model将是最新的。

谢谢。

正如您已经知道的那样,问题是angular不知道jquery插件所做的更新。 幸运的是,您可以使用插件的onSelect回调来更新ngModel,如下所示:

 .directive("autoComplete", function() { return { restrict: "A" , require: 'ngModel', // require ngModel controller scope: { AutoCompleteOptions : "=autoCompleteOptions", // use '=' instead of '&' }, link: function (scope, element, attrs, ngModelCtrl) { // prevent html5/browser auto completion attrs.$set('autocomplete','off'); // add onSelect callback to update ngModel scope.AutoCompleteOptions.onSelect = function() { scope.$apply(function() { ngModelCtrl.$setViewValue(element.val()); }); }; scope.autocomplete = $(element).autocomplete(scope.AutoCompleteOptions); } } }); 

您正在使用的插件具有onSelect回调,因此您只需修改自动完成参数以包含更新范围的回调

 { lookup : $scope.current, width : 448, delimiter : /,/, tabDisabled : true, minChars : 1, onSelect: function(v, data) { $scope.selected_tags = v.value; $scope.$apply(); } 

编辑

要进一步改进这一点,您可以删除在回调中使用模型名称的需要:

 function(v, data) { var model = $(this).attr("ng-model"); $scope[model] = v.value; $scope.$apply(); } 

您的jQuery插件正在更新输入的视图值,但不更新模型。

您必须修改插件才能访问您的模型或范围,否则您必须绑定事件以手动更新视图值中的模型。 也许是这样的:

 $scope.format_tags = function () { $scope.selected_tags = $('#myInput').val(); $scope.selected_final = _.omit($scope.selected_tags.split(','),_.isEmpty); }; 

这是使用此代码的更新版本的代码。

您可以将事件绑定到实际建议的标记元素的单击以获得更好的效果。

我不建议更新插件本身你可以改变你的指令而不是像这样的东西..

 app.directive("autoComplete", function() { return { restrict : "A" , require : '^ngModel', scope : { ngModel: '=', AutoCompleteOptions : "&autoCompleteOptions" }, link : function (scope, element, // prevent html5/browser auto attrs.$set('autocomplete','off'); var options = scope. options.onSelect = function(elem) { scope.$apply(function() { scope.ngModel = elem.value; }); }; scope.autocomplete = $(element).autocomplete(scope.AutoCompleteOptions()); } } }); 

正如您在范围对象初始化中注意到的那样,我已经选择了ngModel属性作为AutoComplete Jquery插件的onSelect事件使用的东西,我在其中使用范围更新了模型。$ apply()方法。 使用范围。$ apply在一个指令中,以便调用范围。$ digest()并直接影响模型。