简体   繁体   English

AngularMaterial自动完成加载动画不会停止

[英]AngularMaterial Autocomplete Loading Animation does not stop

Background: 背景:

I am learning AngularJS and using AngularMaterial. 我正在学习AngularJS并使用AngularMaterial。

To test it, I decided to create an example out of the code given in the documentation (check codepen) . 为了测试它,我决定根据文档中提供的代码创建一个示例(请检查codepen) My application is a nodeJS application in Cloud9 and is very simple. 我的应用程序是Cloud9中的nodeJS应用程序,非常简单。

Code: 码:

It is divided into 3 main files, index.html (which contains the autocomplete box), server.js (containing server logic), and autocomplete.js (client side logic). 它分为3个主要文件: index.html (包含自动完成框), server.js (包含服务器逻辑)和autocomplete.js (客户端逻辑)。

Following are the index.html file and then the autocomplete.js files. 以下是index.html文件,然后是autocomplete.js文件。 Because I have my server running in Cloud9, and this example is linked to it, you can check the small example running live ! 因为我的服务器在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> 

Additionally, here is the code of my server.js file, which uses NodeJs and ExpressJs: 另外,这是我的server.js文件的代码,该文件使用NodeJ和ExpressJ:

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

What works: 什么有效:

Now, if you play around you can select an American state within a list. 现在,如果您四处游玩,可以在列表中选择一个美国州。 The list filters according to what you type and allows you to select something. 该列表根据您键入的内容进行过滤,并允许您选择某些内容。 If you use developer tools you can also see the logs in the console, further demonstrating that the query is working and so is the selection. 如果使用开发人员工具,您还可以在控制台中看到日志,这进一步表明查询正在运行,选择也是如此。

What does not: 什么不是:

The problem here, is when you clear the text box. 这里的问题是当您清除文本框时。 If you pick a state, and then clear it (by pressing the cross or pressing Escape), you will see a blue bar bellow the input box: 如果选择一个状态,然后清除状态(按叉号或按Escape键),则输入框下方会显示一个蓝色条:

blue_bar_under_box

This indicates that a query is being done. 这表明查询正在完成。 The problem is that I don't see any request being sent to the server, and the I get stuck in an infinite query! 问题是我看不到任何发送到服务器的请求,并且卡在了无限查询中! Even when apparently I am not doing it! 即使显然我没有这样做!

What am I missing here? 我在这里想念什么? Can someone help me? 有人能帮我吗?

Extra 额外

For those interested, here is the GitHub repo of the example! 对于那些感兴趣的人,这里是示例的GitHub存储库!

All help is appreciated ! 感谢所有帮助!

Set md-min-length to 1 - you don't really want to be suggesting completions until from an external service until a user has started typing. md-min-length1您真的不希望在用户开始键入之前建议从外部服务完成输入。

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

You're returning the promise from the wrong location and not returning the chain properly, so it doesn't resolve properly. 您从错误的位置返回了诺言,并且未正确返回链,因此无法正确解决。

Try this (note the return in front of the call to $http): 试试这个(注意在调用$ 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 version from the comments. 注释中的TLDR版本。 This is a known bug and the fix isn't released as of this writing. 这是一个已知的错误,在撰写本文时尚未发布此修复程序。 The workaround is either to rollback to AM 1.06 or use css to hide the progressbar. 解决方法是回滚到AM 1.06或使用CSS隐藏进度条。 CSS: CSS:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM