来自 $http 的 Angularjs 自动完成

Posted

技术标签:

【中文标题】来自 $http 的 Angularjs 自动完成【英文标题】:Angularjs autocomplete from $http 【发布时间】:2013-08-29 21:38:35 【问题描述】:

我正在尝试编写一个自动完成指令,该指令使用 $http 请求从服务器获取数据(不使用任何外部插件或脚本)。目前它仅适用于静态数据。现在,我知道我需要将我的 $http 请求插入到指令的 source: 中,但是我找不到任何关于该主题的好的文档。

http 请求

$http.post($scope.url,  "command": "list category() names"). 
            success(function(data, status) 
                $scope.status = status;
                $scope.names = data;    
            )
            .
            error(function(data, status) 
                $scope.data = data || "Request failed";
                $scope.status = status;   
            );

指令

app.directive('autoComplete', function($timeout) 
    return function(scope, iElement, iAttrs) 
            iElement.autocomplete(
                source: scope[iAttrs.uiItems],
                select: function() 
                    $timeout(function() 
                      iElement.trigger('input');
                    , 0);
                
            );
        ;
    );

查看

<input auto-complete ui-items="names" ng-init="manualcat='no category entered'" ng-model="manualcat"> 

那么,我如何以 Angular 的方式正确地将这些拼凑在一起?

【问题讨论】:

能否提供完整的示例源代码?我只是想知道您实际进行 HTTP 调用的时间。提前致谢。 您找到解决方案了吗?我面临同样的问题,加载指令时似乎 $scope.names 为空,ajax 调用被留下 【参考方案1】:

我制作了一个自动完成指令并将其上传到 GitHub。它还应该能够处理来自 HTTP 请求的数据。

这是演示:http://justgoscha.github.io/allmighty-autocomplete/ 这里是文档和存储库:https://github.com/JustGoscha/allmighty-autocomplete

所以基本上,当您想从 HTTP 请求中获取数据时,您必须返回一个 promise,这会在加载数据时得到解决。因此,您必须在发出 HTTP 请求的位置注入 $qservice/directive/controller。

例子:

function getMyHttpData()
  var deferred = $q.defer();
  $http.jsonp(request).success(function(data)
    // the promise gets resolved with the data from HTTP
    deferred.resolve(data);
  );
  // return the promise
  return deferred.promise;

我希望这会有所帮助。

【讨论】:

这对您在下载中包含的模板 html 文件引发了错误。这是必需的吗?如果是这样,您可能希望在文档中明确说明 是否需要将所有数据提取到内存中?如果我有超过 1000 万个变体怎么办? :) @tuxSlayer 下载符合您条件的前 20 个 任何属性来限制结果的数量? 这是否有一个可以设置的超时时间,例如...一旦你停止输入 1 秒后执行一个 http 请求?我不希望它在按下的每个键上都发出请求...@JustGoscha【参考方案2】:

使用 angular-ui-bootstrap 的typehead。

它对 $http 和 promises 有很大的支持。 此外,它根本不包含任何 JQuery,纯 AngularJS。

(我总是更喜欢使用现有的库,如果它们缺少一些东西来打开问题或拉取请求,那么再创建自己的库要好得多)

【讨论】:

感谢乌里戈的回答。但是,就像我在问题中所说的那样,我试图避免使用任何外部脚本。我正在寻找一个纯角度解决方案。干杯,吉顿 请记住,截至今天,angular-ui-bootstrap 中的 Typeahead 与 Angular 1.3 不兼容 谢谢@Rocco,你帮我省了很多麻烦! 如何在选择时获取 id。【参考方案3】:

您需要编写一个在范围内具有ng-change 函数的控制器。在ng-change 回调中,您调用服务器并更新完成。 Here is a stub(没有$http,因为这是一个笨蛋):

HTML

<!doctype html>
<html ng-app="plunker">
    <head>
        <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.js"></script>
        <script src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.4.0.js"></script>
        <script src="example.js"></script>
        <link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css" rel="stylesheet">
    </head>
    <body>
        <div class='container-fluid' ng-controller="TypeaheadCtrl">
            <pre>Model: selected| json</pre>
            <pre>states</pre>
            <input type="text" ng-change="onedit()" ng-model="selected" typeahead="state for state in states | filter:$viewValue">
        </div>
    </body>
</html>

JS

angular.module('plunker', ['ui.bootstrap']);

function TypeaheadCtrl($scope) 
  $scope.selected = undefined;
  $scope.states = [];

  $scope.onedit = function()
    $scope.states = [];

    for(var i = 0; i < Math.floor((Math.random()*10)+1); i++)
      var value = "";

      for(var j = 0; j < i; j++)
        value += j;
      
      $scope.states.push(value);
    
  

【讨论】:

感谢疯子的回答。但是,就像我在问题中所说的那样,我试图避免使用任何外部脚本。在您的回答中,您使用的是 angular-ui 引导脚本。我正在寻找一个纯角度解决方案。干杯,吉顿 我将 angular-ui 用于typeahead 指令(自动完成本身)。【参考方案4】:

在没有外部模块或指令的 angular 或 angularjs 中,最简单的方法是使用 list 和 datalist HTML5。您只需获得一个 json 并使用 ng-repeat 来提供 datalist 中的选项。可以从ajax获取的json。

在这个例子中:

ctrl.query 是您在键入时输入的查询。 ctrl.msg 是在占位符中显示的消息 ctrl.dataList 是获取的json

然后您可以在 ng-reapet 中添加过滤器和 orderby

!! list 和 datalist id 必须同名!!

 <input type="text" list="autocompleList" ng-model="ctrl.query" placeholder=ctrl.msg>
<datalist id="autocompleList">
        <option ng-repeat="Ids in ctrl.dataList value=Ids  >
</datalist>

UPDATE : 是原生 HTML5,但要注意浏览器类型和版本。 看看:https://caniuse.com/#search=datalist。

【讨论】:

【参考方案5】:

我发现this 链接很有帮助

$scope.loadSkillTags = function (query) 
var data = qData: query;
   return SkillService.querySkills(data).then(function(response) 
   return response.data;
  );
 ;

【讨论】:

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

Angularjs Chrome 自动完成的困境

AngularJs中,如何在render完成之后,执行Js脚本

在angularjs中处理来自代理的HTTP 302响应

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

Django 和 AngularJS:如何显示来自 Django 调试错误消息的 Angular $http 错误

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