Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

angularjs - ng-model is not updating when using jquery element.val()

PLUNKR example here

I'm using some version of jquery autocomplete as an angularjs direcitve. When the jquery updates the input's value using element.val() angular does no notice the change until after the next digest ( i suppose ).

My first thought was to perform the action on the ng-model post digest using $timeout but as you can see it didn't help.

My second approach was to override the element's val function to trigger an input event but I haven`t managed to make it work.

Try to select a value from the autocomplete list and you'll see that the ng-model above is not updating.

UPDATE

Thanks for the response. I didn't know about the onSelect option.

This is the code based on your recommendations

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

This way i maintain the interface of the directive while guarantying that ng-model will be up to date.

Thanks.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

As you already knew, the problem is angular doesn't aware of the update made by jquery plugin. Luckily, you can use the plugin's onSelect callback to update ngModel, like this:

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
...