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

标签 javascript angularjs node.js autocomplete angular-material

背景:

我正在学习 AngularJS 并使用 AngularMaterial。

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

代码:

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

以下是 index.html 文件,然后是 autocomplete.js 文件。因为我的服务器在 Cloud9 中运行,并且此示例已链接到它,所以您可以检查实时运行的小示例!

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

什么有效:

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

什么不:

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

blue_bar_under_box

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

我在这里缺少什么?有人可以帮助我吗?

额外

对于那些感兴趣的人,这里是示例的 GitHub 存储库!

感谢所有帮助!

最佳答案

您从错误的位置返回了 promise ,并且没有正确返回链,因此它无法正确解析。

试试这个(注意调用 $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; }

关于javascript - Angular Material 自动完成加载动画不会停止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37609293/

相关文章:

javascript - AngularJS 指令使用 templateURL 加载模板

javascript - 如何在 Angular 应用程序之间共享过滤器

AngularJS : ng-if | Hidden(Removed) ng-model variable not removed from $scope

angularjs - Angular : Reinclude null values when filter parameter is empty

node.js - 我们如何使用 Node.js Connect 映射路径?

javascript - npm 依赖关系不满足(即使它们应该满足?)

javascript - 从 HTTP 请求解析的值不会显示在表中

javascript - 在 jquery 中使用变量,javascript 正则表达式

javascript - 转换 flex/bison 解析器以在浏览器中使用

javascript - 为什么 setInterval() 会给出循环引用?