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

后端 未结 4 1330
天命终不由人
天命终不由人 2020-12-18 09:09

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()

相关标签:
4条回答
  • 2020-12-18 09:36

    Your jQuery plugin is updating the view value of the input, but not the model.

    You will have to modify the plugin to have access to your model or scope or you will have to bind an event to update the model from the view value manually. Maybe something like this:

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

    Here is an updated version of your code using this.

    You could bind an event to the click of the actual suggested tag element for a better effect.

    0 讨论(0)
  • 2020-12-18 09:37

    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);
            }
        }
    });
    
    0 讨论(0)
  • 2020-12-18 09:54

    The plugin you're using has an onSelect callback, so you can simply modify your autocomplete parameters to include a callback which updates the scope

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

    EDIT

    To further improve this you can remove the need to use the model name in the callback:

    function(v, data) {
        var model = $(this).attr("ng-model");
        $scope[model] = v.value;
        $scope.$apply();
    }
    
    0 讨论(0)
  • 2020-12-18 09:57

    I don't recommend updating the plugin itself you can change your directive instead to something like this..

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

    As you've noticed in the scope object initialization of the directive I have selected the ngModel attribute as something to be used by the onSelect event of the AutoComplete Jquery Plugin, where I have updated the model using the scope.$apply() method. Use scope.$apply in a directive so that the scope.$digest() will be invoked and have the model affected directly.

    0 讨论(0)
提交回复
热议问题