Анимация автозаполнения AngularMaterial не останавливается

0

Задний план:

Я изучаю AngularJS и использую AngularMaterial.

Чтобы проверить это, я решил создать пример из кода, приведенного в документации (check codepen). Мое приложение - приложение nodeJS в Cloud9 и очень простое.

Код:

Он разделен на 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);
});

Что работает:

Теперь, если вы играете, вы можете выбрать американское государство в списке. Список фильтрует в соответствии с тем, что вы набираете, и позволяет вам выбрать что-то. Если вы используете инструменты разработчика, вы также можете увидеть журналы в консоли, еще раз продемонстрировав, что запрос работает, а также выбор.

Что нет:

Проблема здесь, когда вы очищаете текстовое поле. Если вы выберите состояние, а затем очистите его (нажав крестик или нажав Escape), вы увидите синюю полосу ниже поля ввода:

Изображение 174551

Это означает, что запрос выполняется. Проблема в том, что я не вижу отправки какого-либо запроса на сервер, а я застрял в бесконечном запросе! Даже когда, видимо, я этого не делаю!

Что мне здесь не хватает? Кто-нибудь может мне помочь?

дополнительный

Для тех, кого это интересует, вот репозиторий GitHub на примере!

Вся помощь приветствуется!

Теги:
angular-material
autocomplete

2 ответа

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


};

Версия TL;DR из комментариев. Это известная ошибка, и исправление не выпущено на момент написания этой статьи. Обходной путь - либо откат до AM 1.06, либо использование css, чтобы скрыть панель прогресса. CSS:

md-autocomplete md-progress-linear { display: none; }
  • 0
    Я проверил с тобой код и после выбора чего-то и очистки, я все еще получаю ту же проблему: S
  • 1
    Я думаю, что вы также пропускаете еще одно возвращение. Я отредактировал ответ, чтобы отразить это.
Показать ещё 15 комментариев
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>
  • 0
    Если я делаю это таким образом, когда пользователь нажимает на поле, ничего не происходит. Я хотел бы показать все состояния, когда пользователь впервые нажимает на поле, поэтому мне нужно иметь min-length="0" . Если бы мне это не нужно, ваш ответ был бы принят. Престижность ++ за попытку.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню