jQuery 自动完成 + AngularJS 的问题

Posted

技术标签:

【中文标题】jQuery 自动完成 + AngularJS 的问题【英文标题】:Problems with jQuery autocomplete + AngularJS 【发布时间】:2012-10-09 04:45:39 【问题描述】:

我在我的页面上使用 AjgularJS,并希望添加一个字段以使用来自 jqueryui 的自动完成功能,并且自动完成功能不会触发 ajax 调用。

我已经在没有 angular(ng-app 和 ng-controller)的页面上测试了脚本,它运行良好,但是当我将脚本放在有 angularjs 的页面上时,它停止工作。

有什么想法吗?

jquery 脚本:

$(function () 

    $('#txtProduct').autocomplete(
        source: function (request, response) 

            alert(request.term);

        ,
        minLength: 3,
        select: function (event, ui) 

        
    );

);
有趣的提示:当我在 Chrome 检查器上调用脚本时,自动完成功能开始工作!!! 版本:AngularJS:1.0.2 - JqueryUI:1.9.0

结论: jQueryUI 的自动完成小部件必须从 AngularJS 的自定义指令内部初始化,例如:

标记

<div ng-app="TestApp">
    <h2>index</h2>
    <div ng-controller="TestCtrl">

        <input type="text" auto-complete>ddd</input>

    </div>
</div>

角度脚本

<script type="text/javascript">

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

    function TestCtrl($scope)  

    app.directive('autoComplete', function () 
        return function postLink(scope, iElement, iAttrs) 

            $(function () 
                $(iElement).autocomplete(
                    source: function (req, resp) 
                        alert(req.term);
                    
                );
            );

        
    );

</script>

【问题讨论】:

您应该尝试将它们加载到 $(document).ready();还要检查 firebug 控制台中的错误。 同意 - 您需要检查 AngularJS 和 JQuery 之间的冲突。在一个简单的测试中似乎没有:jsfiddle.net/mccannf/w69Wt 这可能与您看到的问题无关,但我认为您应该在自定义指令(链接函数)中使用 jquery。 谢谢大家,对我有用的解决方案是 tosh 建议的,为此创建了一个自定义指令!!! 【参考方案1】:

也许你只需要以一种“角度的方式”来做......也就是说,使用指令来设置你的 DOM 元素并进行事件绑定,使用服务来获取你的数据,并使用控制器来做你的业务逻辑......同时利用 Angular 的依赖注入优点......

获取自动完成数据的服务...

app.factory('autoCompleteDataService', [function() 
    return 
        getSource: function() 
            //this is where you'd set up your source... could be an external source, I suppose. 'something.php'
            return ['apples', 'oranges', 'bananas'];
        
    
]);

用于设置自动完成插件的指令。

app.directive('autoComplete', function(autoCompleteDataService) 
    return 
        restrict: 'A',
        link: function(scope, elem, attr, ctrl) 
                    // elem is a jquery lite object if jquery is not present,
                    // but with jquery and jquery ui, it will be a full jquery object.
            elem.autocomplete(
                source: autoCompleteDataService.getSource(), //from your service
                minLength: 2
            );
        
    ;
);

并在您的标记中使用它...注意 ng-model 使用您选择的内容在 $scope 上设置一个值。

<div ng-controller="Ctrl1">
    <input type="text" ng-model="foo" auto-complete/>
    Foo = foo
</div>

这只是基础知识,但希望对您有所帮助。

【讨论】:

elem.autocomplete 需要是 $(elem).autocomplete @AshMcConnell:如果 jQuery 在 Angular 之前的页面上注册,则链接函数的 elem 参数已经是一个 jQuery 对象。所以不需要 $() 。 ;) Angular 就是这样光滑的。 谢谢!不知道啊,明天上班我去查进口单! (这只是你的意思进口的顺序?) 正确,只要你的&lt;script src="jquery.js"&gt;&lt;/script&gt;在你的&lt;script src="angular.js"&gt;&lt;/script&gt;之前,它应该使用jQuery对象而不是Angular中的元素的jqLit​​e对象。 工作完美。谢谢!【参考方案2】:

我必须做更多的工作才能使用 $http 服务来完成这项工作。

服务:

app.factory("AutoCompleteService", ["$http", function ($http) 
    return 
        search: function (term) 
            return $http.get("http://YourServiceUrl.com/" + term).then(function (response) 
                return response.data;
            );
        
    ;
]);

指令:

app.directive("autocomplete", ["AutoCompleteService", function (AutoCompleteService) 
    return 
        restrict: "A",
        link: function (scope, elem, attr, ctrl) 
            elem.autocomplete(
                source: function (searchTerm, response) 
                    AutoCompleteService.search(searchTerm.term).then(function (autocompleteResults) 
                        response($.map(autocompleteResults, function (autocompleteResult) 
                            return 
                                label: autocompleteResult.YourDisplayProperty,
                                value: autocompleteResult 
                            
                        ))
                    );
                ,
                minLength: 3,
                select: function (event, selectedItem) 
                    // Do something with the selected item, e.g. 
                    scope.yourObject= selectedItem.item.value;
                    scope.$apply();
                    event.preventDefault();
                
            );
        
    ;
]);

html:

<input ng-model="YourObject" autocomplete />

【讨论】:

我收到以下错误“错误:未定义自动完成结果” 您的服务是否返回任何信息?例如,在我的服务中,我返回 response.data。如果您还返回它,请确保您的服务调用也返回数据。 @Jason: 你能告诉我get方法中json返回数据的格式吗? @Siddesh Bhalke:您的服务可以返回任意 json。在此示例中,autocompleteResults 是一个对象数组,每个对象都有一个名为“YourDisplayProperty”的属性。 我遇到了一个问题,即列表在任何人点击任何内容之前就消失了。我用 corolla 的解决方案解决了这个问题:***.com/questions/6043506/…【参考方案3】:

HTML

 <input type="text" class="form-control ml-2" employeesearchautocomplete ng-model="employeeName" name="employeeName">

JS

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

        myApp.controller("employeeSearchController",function($scope,$http)

            $scope.message= "Welcome to angular js..."

        );

        myApp.directive('employeesearchautocomplete', function() 
            return 
                restrict: 'A',
                require : 'ngModel',
                link : function (scope, element, attrs, ngModelCtrl) 
                      element.autocomplete(
                          source : function(request, response) 
                            $.ajax(
                                type : "POST",
                                url : "searchEmployee.html",
                                data : request,
                                success : response,
                                dataType : 'json'
                            );
                        ,
                        select : function(event, ui) 
                            event.preventDefault();
                            if (ui.item.value == '-1') 
                                scope.employeeName ='';
                                scope.$apply();
                             else 
                                scope.employeeName = ui.item.label;
                                scope.$apply();

                            
                        ,
                        focus : function(event, ui) 
                            event.preventDefault();
                            scope.employeeName = ui.item.label;
                            scope.$apply();
                        ,
                        change : function(event, ui) 
                            if (!ui.item) 
                                scope.employeeName ='';
                                scope.$apply();

                            
                        
                      ,
                            minLength : 2
                      );


                
            
        );

脚本文件导入顺序

你所有的 jquery AngularJs 库 用于自动完成的 Angular 脚本

我希望这会对某人有所帮助。

【讨论】:

以上是关于jQuery 自动完成 + AngularJS 的问题的主要内容,如果未能解决你的问题,请参考以下文章

如何自动大写AngularJS输入字段中的第一个字符?

Angularjs Chrome 自动完成的困境

来自 $http 的 Angularjs 自动完成

AngularJS - 在谷歌自动完成中限制国家

kendoui + angularjs + 自动完成显示文本但将 id 设置为值

如何将标题添加到 jqueryui 自动完成调用?