【问题标题】:Angular directive md-autocomplete with Google Maps autocompleteService带有 Google Maps autocompleteService 的 Angular 指令 md-autocomplete
【发布时间】:2016-03-28 13:13:24
【问题描述】:

提前感谢您的帮助。

我一直在尝试设置一个自动完成搜索框,以便使用 Angular 与 google AutocompleteService API 进行交互。

目前,我的 Angular AutocompleteService 运行良好,并根据在搜索栏中输入的内容检索一系列建议的预测。

这是我的自动完成服务:

  angular
    .module('LocalKnowledgeApp')
    .service('AutocompleteService', [ function() {

var self = this;
var suggestions = [];



  self.initPredict = function(searchInput) {
    var predict = new google.maps.places.AutocompleteService();
    predict.getQueryPredictions({ input: searchInput }, self.displaySuggestions);
  };

  self.displaySuggestions = function(predictions, status) {
    if (status != google.maps.places.PlacesServiceStatus.OK) {
      console.log(status);
      return;
    }
    predictions.forEach(function(prediction) {
      suggestions.push(prediction.description);
    });
  };

  self.makeSuggestions = function(){
    return suggestions.slice(0,10);
  };

该服务被注入到控制器中,该控制器控制我尝试连接到自动完成的表单。 (我只包含了涉及到自动完成位并与 AutocompleteService 交互的函数)

angular
    .module('LocalKnowledgeApp')
    .controller('RequestController', ['LocationService', 'MarkersService', 'AutocompleteService', '$http', '$scope',
        function(LocationService, MarkersService, AutocompleteService, $http, $scope) {

    var self = this;
    var isInfoOpen = false;
    var clickedRequest = {};
    var requestUser = {};
    var autocompleteStarted;
    self.master = {};
    var autocompleteSuggestions = [];

    // var search = autoCompleteSearch;


    self.autoCompleteSearch = function(searchInput){
        if (searchInput.length < 2) {
        self.autocompleteStarted = false;
      } else {
        AutocompleteService.initPredict(searchInput);
        self.autocompleteStarted = true;
        self.autocompleteSuggestions = AutocompleteService.makeSuggestions();
        return self.autocompleteSuggestions;
      }
    };

我现在正在尝试连接以在搜索栏上获得一个下拉框,以便用户可以从 Google 自动完成服务返回到 RequestsController 的建议数组中进行选择。

<div id="myModal" class="modal fade" role="dialog">
  <div class="modal-dialog">
    <!-- Modal content-->
    <div class="modal-content" >
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal">&times;</button>
        <h4 class="modal-title">Request a tour from a local</h4>
      </div>
      <div class="modal-body">
        <form>
          <div class="form-group">
            <label for="location">Location</label>
            <div>
            <md-autocomplete
                md-search-text-change="r.autoCompleteSearch(searchText)"
                md-input-name="request.location"
                md-selected-item="selectedItem"
                md-search-text="searchText"
                md-items="item in r.autocompleteSearch(searchText)"
                md-item-text="item.display"
                md-input-minlength="0">
              <md-item-template md-highlight-text="searchText">
                {{item.display}}
              </md-item-template>
            </div>
            </md-autocomplete>

            <aside ng-show="r.autocompleteStarted" id="autocompleteSuggestions">
              <ul ng-repeat="suggestion in r.autocompleteSuggestions track by $index"> {{suggestion}} </ul>
            <aside>
          </div>

我已经注入了 ngMaterial 模块,并且在正确的位置拥有了所有需要的 bower 组件——我知道这一点是因为指令响应输入,但它只显示一个灰色框。

(function() {
  'use strict';

  angular
    .module('LocalKnowledgeApp', ['ngResource', 'ngMaterial']);

}());

这就是我的网页的样子...

[

非常感谢任何帮助!

【问题讨论】:

    标签: angularjs autocomplete md-autocomplete google-maps-autocomplete


    【解决方案1】:

    角度指令:

    'use strict';
    
    angular.module('locationApp', ['ngAnimate', 'ngMaterial']);
    angular.module('locationApp')
    .controller('HomeCtrl', function ($scope) {
        // $scope.location={};
    
    });
    /**
     * @ngdoc directive
     * @name locationApp.directive:placeAutocomplete
     * @description
     *
     * # An element directive that provides a dropdown of
     * location suggestions based on the search string.
     * When an item is selected, the location's latitude
     * and longitude are determined.
     * 
     * This directive depends on the Google Maps API
     * with the places library
     * 
     * <script src="https://maps.googleapis.com/maps/api/js?libraries=places"></script>
     * 
     * Usage:
     * <place-autocomplete ng-model="selectedLocation"></place-autocomplete>
     *
     * Credit:
     * http://stackoverflow.com/a/31510437/293847
     */
    angular.module('locationApp')
      .directive('placeAutocomplete', function () {
          return {
              templateUrl: 'place-autocomplete.html',
              restrict: 'AEC',
              replace: true,
              scope: {
                  'ngModel': '='
              },
              controller: function ($scope, $q) {
                  if (!google || !google.maps) {
                      throw new Error('Google Maps JS library is not loaded!');
                  } else if (!google.maps.places) {
                      throw new Error('Google Maps JS library does not have the Places module');
                  }
                  console.log('google.maps.places ', google.maps.places);
                  var autocompleteService = new google.maps.places.AutocompleteService();
                  var map = new google.maps.Map(document.createElement('div'));
                  var placeService = new google.maps.places.PlacesService(map);
                  console.log('google.maps.places ', placeService);
                  $scope.ngModel = {};
    
                  /**
                   * @ngdoc function
                   * @name getResults
                   * @description
                   *
                   * Helper function that accepts an input string
                   * and fetches the relevant location suggestions
                   *
                   * This wraps the Google Places Autocomplete Api
                   * in a promise.
                   *
                   * Refer: https://developers.google.com/maps/documentation/javascript/places-autocomplete#place_autocomplete_service
                   */
                  var getResults = function (address) {
                      var deferred = $q.defer();
                      console.log('address ', address, autocompleteService)
                      autocompleteService.getQueryPredictions({
                          input: address,
                          component: {
                              country: 'IN'
                          }
                      }, function (data) {
                          deferred.resolve(data);
                      });
                      return deferred.promise;
                  };
    
                  /**
                   * @ngdoc function
                   * @name getDetails
                   * @description
                   * Helper function that accepts a place and fetches
                   * more information about the place. This is necessary
                   * to determine the latitude and longitude of the place.
                   *
                   * This wraps the Google Places Details Api in a promise.
                   *
                   * Refer: https://developers.google.com/maps/documentation/javascript/places#place_details_requests
                   */
                  var getDetails = function (place) {
                      var deferred = $q.defer();
                      placeService.getDetails({
                          'placeId': place.place_id
                      }, function (details) {
                          deferred.resolve(details);
                      });
                      return deferred.promise;
                  };
    
                  $scope.search = function (input) {
                      if (!input) {
                          return;
                      }
                      return getResults(input).then(function (places) {
                          return places;
                      });
                  };
                  /**
                   * @ngdoc function
                   * @name getLatLng
                   * @description
                   * Updates the scope ngModel variable with details of the selected place.
                   * The latitude, longitude and name of the place are made available.
                   *
                   * This function is called every time a location is selected from among
                   * the suggestions.
                   */
                    $scope.getLatLng = function (place) {
                    if (!place) {
                        $scope.ngModel = {};
                        return;
                    }
                    getDetails(place).then(function (details) {
                        $scope.ngModel = {
                            'name': place.description,
                            'latitude': details.geometry.location.lat(),
                            'longitude': details.geometry.location.lng(),
                        };
                    });
                }
            }
        };
    });
    

    HTML 部分:

    <!DOCTYPE html>
    <html ng-app="locationApp">
        <head>
            <!-- <link rel="stylesheet" href="place-autocomplete.css" /> -->
            <link rel="stylesheet" href="//rawgit.com/angular/bower-material/master/angular-material.css" />
    
            <script data-require="angular.js@1.4.8" data-semver="1.4.8" src="https://code.angularjs.org/1.4.8/angular.js"></script>
            <!-- <script data-require="angular-route.js@1.4.8" data-semver="1.4.8" src="https://code.angularjs.org/1.4.8/angular-route.js"></script> -->
            <script data-require="angular-aria@1.4.0" data-semver="1.4.0" src="https://code.angularjs.org/1.4.0/angular-aria.js"></script>
            <script data-require="angular-animate@1.4.8" data-semver="1.4.8" src="https://code.angularjs.org/1.4.8/angular-animate.js"></script>
            <script src="//rawgit.com/angular/bower-material/master/angular-material.js"></script>
            <script src="https://maps.googleapis.com/maps/api/js?libraries=places"></script>
            <script src="place-autocomplete.js"></script>
        </head>
    
        <body>
            <md-content>
                <md-toolbar>
                    <div class="md-toolbar-tools">
                        <h2>
                            <span>Google places/location suggestions with md-autocomplete</span>
                        </h2>
                        <span flex></span>
                    </div>
                </md-toolbar>
            </md-content>
            <md-content layout-padding>
                <p>Start typing the name of a place/location below</p>
                <div class="md-padding">
                    <place-autocomplete ng-model="location"></place-autocomplete>
                    <place-autocomplete ng-model="location1"></place-autocomplete>
                    <place-autocomplete ng-model="location2"></place-autocomplete>
                    <place-autocomplete ng-model="location3"></place-autocomplete>
                    {{location}}
                    {{location1}}
                    {{location2}}
                    {{location3}}
                    <script type="text/ng-template" id="place-autocomplete.html">
                        <div>
                            <md-autocomplete md-no-cache="false" md-selected-item="location" md-selected-item-change="getLatLng(item)" ng-model-options="{debounce: 600}" md-search-text-change="search(searchText)" md-search-text="searchText" md-items="item in search(searchText)" md-item-text="item.description" md-min-length="2" md-max-length="50" md-floating-label="Location (place, city or region)">
                                <md-item-template>
                                    <span md-highlight-text="searchText" md-highlight-flags="^i">{{item.description}}</span>
                                </md-item-template>
                                <md-not-found>
                                    No matches found for "{{searchText.description}}".
                                </md-not-found>
                            </md-autocomplete>
                        </div>
                    </script>
                    <div ng-if="location.name">
                        <h4>Selected location</h4>
                        <pre>{{location}}</pre>
                    </div>
                </div>
            </md-content>
        </body>
    </html>
    

    更多详情:

    https://gist.github.com/vinaygopinath/49df0b58a276281e5ffa

    【讨论】:

      猜你喜欢
      • 2015-07-27
      • 2019-11-11
      • 1970-01-01
      • 2020-08-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多