Angular Material 自动完成加载动画不会停止

AngularMaterial Autocomplete Loading Animation does not stop

背景:

我正在学习 AngularJS 并使用 AngularMaterial。

为了测试它,我决定根据 documentation (check codepen) 中给出的代码创建一个示例。我的应用程序是 Cloud9 中的 nodeJS 应用程序,非常简单。

代码:

它分为 3 个主要文件,index.html(包含自动完成框)、server.js(包含服务器逻辑)和 autocomplete.js(客户端逻辑)。

以下是 index.html 文件,然后是 autocomplete.js 文件。因为我的服务器运行在Cloud9,这个例子链接到它,你可以查看小例子运行 live !

/*global angular*/

'use strict';
angular.module('MyApp', ['ngMaterial', 'ngMessages', 'material.svgAssetsCache']).controller('DemoCtrl', DemoCtrl);

function DemoCtrl($q, $log, $http) {
    
    this.searchText = null;
    
    this.querySearch =function(query) {
        let serverUrl = '//material-complete-fl4m3ph03n1x.c9users.io/getStates';
        let deferred = $q.defer();
        $http({
            method: 'GET',
            url: serverUrl,
            params: {
                word: query
            }
            
        }).then(function successCallback(response) {
            deferred.resolve(response.data);
        }, function errorCallback(response) {
            $log.error(response);
        });

        return deferred.promise;
    };

    this.searchTextChange = function(text) {
        $log.info('Text changed to ' + text);
    };

    this.selectedItemChange = function(item) {
        $log.info('Item changed to ' + JSON.stringify(item));
    };
}
<html lang="en">

<head>
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>

<body ng-app="MyApp" ng-cloak>

    <div ng-controller="DemoCtrl as ctrl" layout="column" ng-cloak="" class="autocompletedemoBasicUsage" ng-app="MyApp">
        <md-content class="md-padding">
            <form ng-submit="$event.preventDefault()">

                <md-autocomplete md-search-text-change="ctrl.searchTextChange(ctrl.searchText)" md-search-text="ctrl.searchText" md-selected-item-change="ctrl.selectedItemChange(item)" md-items="item in ctrl.querySearch(ctrl.searchText)" md-item-text="item.display" md-min-length="0"
                placeholder="What is your favorite US state?">
                    <md-item-template>
                        <span md-highlight-text="ctrl.searchText" md-highlight-flags="^i">{{item.display}}</span>
                    </md-item-template>
                    <md-not-found>
                        No states matching "{{ctrl.searchText}}" were found.
                    </md-not-found>
                </md-autocomplete>
                <br>

            </form>
        </md-content>
    </div>

    <!--CSS files-->
    <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/angular_material/1.1.0-rc4/angular-material.min.css">
    <link rel="stylesheet" href="https://material.angularjs.org/1.1.0-rc4/docs.css">
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700,400italic">

    <!-- Angular Material requires Angular.js Libraries -->
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-animate.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-route.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-aria.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-messages.min.js"></script>
    <script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/t-114/svg-assets-cache.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angular_material/1.1.0-rc4/angular-material.min.js"></script>

    <!-- Your application bootstrap  -->
    <script type="text/javascript" src="js/autocomplete.js"></script>
</body>

</html>

此外,这是我的 server.js 文件的代码,它使用了 NodeJs 和 ExpressJs:

//Lets define a port we want to listen to
const PORT = 8080;

//Init Vars
var express = require('express');
var app = express();

//Init Functions
//we allow CORS: http://enable-cors.org/server_expressjs.html
app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});

app.listen(PORT, function() {
  console.log('Example app listening on port ' + PORT + '!');
});

//GET methods
app.get('/getStates', function(req, res, next) {

  var createFilterFor = function(query) {
    var lowercaseQuery = query.toLowerCase();

    return function filterFn(state) {
      return (state.value.indexOf(lowercaseQuery) > -1);
    };

  };

  //get parameters from GET: https://scotch.io/tutorials/use-expressjs-to-get-url-and-post-parameters
  var query = req.param('word');

  var allStates = 'Alabama, Alaska, Arizona, Arkansas, California, Colorado, Connecticut, Delaware,\
              Florida, Georgia, Hawaii, Idaho, Illinois, Indiana, Iowa, Kansas, Kentucky, Louisiana,\
              Maine, Maryland, Massachusetts, Michigan, Minnesota, Mississippi, Missouri, Montana,\
              Nebraska, Nevada, New Hampshire, New Jersey, New Mexico, New York, North Carolina,\
              North Dakota, Ohio, Oklahoma, Oregon, Pennsylvania, Rhode Island, South Carolina,\
              South Dakota, Tennessee, Texas, Utah, Vermont, Virginia, Washington, West Virginia,\
              Wisconsin, Wyoming';

  var statesMap = allStates.split(/, +/g).map(
    function(state) {
      return {
        value: state.toLowerCase(),
        display: state
      };
    });

  var result = query ? statesMap.filter(createFilterFor(query)) : statesMap;
  res.send(result);
});

什么有效:

现在,如果您四处游玩,您可以 select 列表中的一个美国州。该列表根据您键入的内容进行过滤,并允许您 select 某些内容。如果您使用开发人员工具,您还可以在控制台中看到日志,进一步证明查询正在运行,selection 也是如此。

什么没有:

这里的问题是当您清除文本框时。如果您选择一个状态,然后清除它(通过按叉号或按 Escape),您将在输入框下方看到一个蓝色条:

这表示查询正在进行中。问题是我没有看到任何请求被发送到服务器,我陷入了无限查询!即使显然我没有这样做!

我在这里错过了什么?有人可以帮助我吗?

额外

对于那些感兴趣的人,这里是示例的 GitHub 回购协议!

感谢所有帮助!

md-min-length 设置为 1 - 在用户开始输入之前,您并不真正希望从外部服务建议完成。

<md-autocomplete 
  md-search-text-change="ctrl.searchTextChange(ctrl.searchText)" 
  md-search-text="ctrl.searchText" md-selected-item-change="ctrl.selectedItemChange(item)" 
  md-items="item in ctrl.querySearch(ctrl.searchText)" 
  md-item-text="item.display"
  md-min-length="1"
  placeholder="What is your favorite US state?">
  <md-item-template>
    <span md-highlight-text="ctrl.searchText" md-highlight-flags="^i">{{item.display}}</span>
  </md-item-template>
  <md-not-found>
    No states matching "{{ctrl.searchText}}" were found.
  </md-not-found>
</md-autocomplete>

您 return 从错误的位置获取承诺,而不是正确地 return 获取链,因此它无法正确解析。

试试这个(注意 $http 调用前面的 return):

this.querySearch =function(query) {
    let serverUrl = '//material-complete-fl4m3ph03n1x.c9users.io/getStates';
    let deferred = $q.defer();
    return $http({
        method: 'GET',
        url: serverUrl,
        params: {
            word: query
        }

    }).then(function successCallback(response) {
        if(response.data.length>0) {
            deferred.resolve(response.data); }
        else {
            var nada=[]
            deferred.resolve(nada); }
        }
        return deferred.promise;
    }, function errorCallback(response) {
        $log.error(response);
        deferred.reject(response);
        return deferred.promise;
    });


};

来自评论的 TLDR 版本。这是一个已知错误,在撰写本文时尚未发布修复程序。解决方法是回滚到 AM 1.06 或使用 css 隐藏进度条。 CSS:

md-autocomplete md-progress-linear { display: none; }