AngularMaterial自动填充加载动画不会停止

时间:2016-06-03 08:13:10

标签: 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>
&#13;
&#13;
&#13;

此外,这是我的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);
});

什么有效:

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

什么不是:

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

blue_bar_under_box

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

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

附加

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

感谢所有帮助!

2 个答案:

答案 0 :(得分:1)

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>

答案 1 :(得分:1)

您将从错误的位置返回承诺,而不是正确返回链,因此无法正确解析。

试试这个(注意在$ http调用前返回):

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